diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 314e198..0000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/* -rollup-config.js -custom-elements.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 5c4869c..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "root": true, - "extends": [ - "eslint:recommended", - "plugin:storybook/recommended" - ], - "parser": "babel-eslint", - "globals": { - "chai": "readonly" - }, - "parserOptions": { - "sourceType": "module" - }, - "env": { - "browser": true, - "mocha": true - }, - "rules": { - "no-unexpected-multiline": "off" - }, - "overrides": [ - { - "files": [ - "rollup.config.js" - ], - "env": { - "node": true - } - } - ] -} diff --git a/.gitignore b/.gitignore index 879c140..50670db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ node_modules/ +.stencil/ custom-elements.json # Only generated for size check my-element.bundled.js .turbo -storybook-static .DS_Store .env + +dist/ +loader/ +storybook-static/ diff --git a/.prettierrc.json b/.prettierrc.json index 7f76f53..9cf80db 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -2,5 +2,5 @@ "htmlWhitespaceSensitivity": "ignore", "semi": false, "singleQuote": true, - "trailingComma": "es5" + "trailingComma": "all" } diff --git a/.storybook/main.js b/.storybook/main.js index 376fe64..96474de 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,9 +1,31 @@ -/** @type { import('@storybook/web-components-vite').StorybookConfig } */ +import { join, dirname } from 'path' + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value) { + return dirname(require.resolve(join(value, 'package.json'))) +} + +/** @type { import('@storybook/html-vite').StorybookConfig } */ const config = { - framework: { name: '@storybook/web-components-vite' }, - stories: ['../{src,docs}/**/*.mdx', '../{src,docs}/**/*.stories.js'], - addons: ['@storybook/addon-links', '@storybook/addon-essentials'], - docs: { autodocs: true }, + stories: [ + '../{src,docs}/**/*.mdx', + '../{src,docs}/**/*.stories.@(js|jsx|mjs|ts|tsx)', + ], + addons: [ + getAbsolutePath('@storybook/addon-links'), + getAbsolutePath('@storybook/addon-essentials'), + getAbsolutePath('@storybook/addon-interactions'), + ], + framework: { + name: getAbsolutePath('@storybook/html-vite'), + options: {}, + }, + docs: { + autodocs: 'tag', + }, } export default config diff --git a/.storybook/preview.js b/.storybook/preview.js index 8ec9ac9..b028ca8 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,13 +1,11 @@ -import { setCustomElementsManifest } from '@storybook/web-components' -import { html } from 'lit' -import { styleMap } from 'lit/directives/style-map.js' -import customElementsManifest from '../custom-elements.json' +import { defineCustomElements } from '../loader' +import { html } from '../src/utils/html' import '../src/theme.css' import '../src/theme-typography.css' import '../src/styles.css' import './preview.css' -setCustomElementsManifest(customElementsManifest) +defineCustomElements() const defaultStyles = { padding: 'var(--spacing-xl)', @@ -18,9 +16,16 @@ const preview = { decorators: [ (story, { parameters }) => { const { styles = defaultStyles } = parameters + console.log({ styles }) + const style = Object.entries(styles) + .map( + ([key, value]) => console.log({ key, value }) || `${key}: ${value}`, + ) + .join('; ') + console.log({ style }) return html` -
- Figuring out a good office setup in the RV took some doing. Like, a LOT - of doing. But in the end, I'm very happy with the results. I actually - have a couple different work setups - the main "office" in the hallway - of our RV, and an outdoor setup I use in our tent when the weather - allows. I also have a more mobile setup I can use anywhere, for when the - internet at the campground calls it quits and says, "Not today, buddy! - Not today." Flexibility is the name of the game in full time RV life. -
-- The hallway is my "office" in the RV. We have a 36 foot fifth wheel with - a mid bunk. The bedroom in the middle of the RV would probably be the - most natural choice for an office space, if it didn't belong to our - daughter, Lennon. I might hold that against her if she wasn't literally - the cutest human in the entire universe. -
- -- So the hallway it is. My hallway setup involves a - - floor to ceiling autopole - - that I mount my monitor on. I had no idea what an autopole was before I - started this venture. It's something you'd find in a photography or - video studio, which they use to mount lights, backdrops, and that kind - of stuff. The pole is pressure fit, which means we didn't have to drill - any holes to mount it. I bought a - - monitor arm - - that's made to mount to the pole, and it's held up my 34" ultra-wide - monitor for a couple years now without skipping a beat. -
-- My "standing desk" is actually a - - percussion table - - . Like the kind a drummer would use to hold a laptop next to them while - they're drumming. I ordered a custom mouse pad to fit the exact - dimensions of the percussion table, and secured it with washers and - bolts in the four corners. -
-- I also use an - - anti-fatigue standing mat - - so my feet don't get too tired from standing the whole day. If I do get - tired, I have a very slim, foldable, - - height-adjustable chair - - I can whip out and set up in the hallway. It's not the most comfortable - chair in the world, but it folds completely flat, and stows away nicely. - And it does the job to give my feet a break when they need one. I've - gotten more and more used to standing while working, so I rarely use the - chair any more. But it definitely comes in handy. -
-- The tent office is a more recent addition. We purchased a - - Clam Quick-Set tent - - , and we're in love with it. We went back and forth on that decision - for, I dunno, at least 6 months, but we definitely should have purchased - one earlier. We got the "Pavilion" model, which is 12.5 by 12.5 feet, so - it's basically the same size as our main kitchen/living area in the RV. -
- -- In the tent, we have a collapsible camping table from REI that I set up. - On the table I set up my laptop on a - - Nexstand laptop stand - - , so the screen is higher up and I'm not hunching over to look down at - it and wrecking my back. Then I can use my external mouse and keyboard - like normal. I set up my collapsible chair I mentioned earlier, and - BOOM! Outdoor office, baby! It really is a dreamy setup when it's cool - outside, and a light breeze is blowing. Couldn't ask for a better - office. -
- -- And then comes the mobile office. We've all been there. Sometimes the - internet at the campground just can't. We have a Verizon and AT&T - plan, so usually between the two of them we can work things out. But not - always. For those times, I take basically the same setup I have in the - outdoor tent on the road. The laptop, stand, mouse, and keyboard all fit - in a little backpack. So usually I can just set that up at a coffee shop - or library and be good to go. I'll always throw an extension cord in the - backpack just in case there's not an outlet close by. And I'll usually - throw the collapsible table in the truck just in case. It has definitely - come in handy a time or two. -
-- As a last resort, I can set up directly in the truck itself. I have a - headrest laptop mount that holds the laptop on the back of the driver - headrest (although I can't actually find a link to this product on - Amazon anymore, so it may have been discontinued). I can prop the laptop - up there, and sit in the back seat with a - - portable laptop tray - - to hold my mouse and keyboard. This setup is always my last resort, if - the internet at the campground is a no go, and the weather outside is - ghastly, and it's a global pandemic and I'm not allowed inside of any - buildings. Things happen, ya know? But it works surprisingly well when - there's nothing else. -
-- So there you have it. RV office. Like I said, flexibility is key. I'll - post links below to some of the different products I use. Feel free to - hit us up with any questions or recommendations. -
- - Autopole - Manfrotto - - - Monitor pole mount - Chief - - - Percussion table laptop stand - Meinl - - - Topo Mini anti-fatigue standing mat - Ergodriven - - - Height adjustable folding chair - Vestil - - - Vertical laptop stand - Omoton - - - Quick-Set Pavilion tent - Clam - - - Portable laptop stand - Nexstand - - - Portable laptop tray - Max Smart - -
- Here’s a little cheat-sheet for how to use JSX in Vue. JSX is less
- popular in Vue than React, because Vue already has a very good, easy
- to learn HTML templating system. However, I found myself reaching for
- JSX more often due to the increased flexibility. For example, I’m a
- very big fan of adding an
- as
- prop to my components, to easily change the HTML tag or component that
- gets rendered.
-
<AppButton as="a" href="#link">
Button Link
</AppButton>
-
- I found myself using a lot of render functions for this sort of
- functionality. And once you’re using render functions, JSX is MUCH
- easier to use than stringing together a bunch of
- createElement
- functions.
-
- Props can be accessed via
- this.$props
- . All additional attributes passed to the component are available via
- this.$attrs
- , and are automatically added to the root component.
-
export default {
name: 'AppButton',
props: {
size: String,
},
render() {
const { size } = this.$props
return (
<button class={size}>
{this.$slots.default}
</button>
)
},
}
- <AppButton size="sm" id="submit">
Submit
</AppButton>
<!-- Result -->
<button class="sm" id="submit">
Submit
</button>
-
- If you want to manually handle how extra attributes are passed to the
- DOM, you can add
- inheritAttrs: false
- to your component. You might do this if you want those attributes to
- pass to a nested element instead of the root, for example. The one
- exception is
- class
- and
- style
- , which are always automatically merged with the root element,
- regardless of
- inheritAttrs
- .
-
export default {
name: 'AppButton',
inheritAttrs: false,
props: {
size: String,
},
render() {
const { size } = this.$props
return (
<div class="root">
<button class={size} attrs={this.$attrs}>
{this.$slots.default}
</button>
</div>
)
},
}
- <AppButton size="sm" id="submit" class="my-button">
Submit
</AppButton>
<!-- Result -->
<div class="root my-button">
<button class="sm" id="submit">
Submit
</button>
</div>
- export default {
name: 'AppButton',
render() {
return (
<button {...{ on: this.$listeners }}>
{this.$slots.default}
</button>
)
},
}
- babel-plugin-transform-vue-jsx
-Spreading props, attributes, listeners
-