From 5db622e9da3548d65738bab4dd119c169bbebd5c Mon Sep 17 00:00:00 2001 From: Thomas Allmer Date: Mon, 15 Mar 2021 10:54:44 +0100 Subject: [PATCH] feat: as BREAKING CHANGE add exports & convert to static docs page --- .changeset/early-dolphins-build.md | 5 + .changeset/famous-bears-confess.md | 23 + .changeset/odd-beds-clean.md | 5 + .changeset/silly-ants-melt.md | 40 + .eleventyignore | 4 + .eslintignore | 2 + .eslintrc.js | 2 + .gitignore | 11 +- .markdownlint.json | 3 + .prettierignore | 2 + .storybook/main.js | 81 - .storybook/preview-head.html | 27 - .storybook/preview.js | 49 - README.md | 85 +- assets/logo.png | Bin 0 -> 19142 bytes demo/docs/20-lea-tabs.md | 231 - demo/lea-tab-panel.js | 3 - demo/lea-tab.js | 3 - demo/lea-tabs.js | 3 - docs/404.md | 4 + docs/README.md | 13 - .../_static/icons/android-chrome-192x192.png | Bin 0 -> 9925 bytes .../_static/icons/android-chrome-512x512.png | Bin 0 -> 32835 bytes .../_static/icons/apple-touch-icon.png | Bin 0 -> 6223 bytes docs/_assets/_static/icons/favicon-16x16.png | Bin 0 -> 837 bytes docs/_assets/_static/icons/favicon-32x32.png | Bin 0 -> 1375 bytes docs/_assets/_static/icons/mstile-150x150.png | Bin 0 -> 5770 bytes .../_static/icons/safari-pinned-tab.svg | 39 + docs/_assets/logo.svg | 31 + docs/_assets/style.css | 23 + docs/_assets/variables.css | 41 + docs/_data/footer.json | 41 + docs/_data/site.cjs | 22 + docs/about/slack.md | 5 + docs/blog/controlling-exports.md | 173 + docs/{ => blog}/extending-documentation.md | 35 +- docs/blog/extending-lions-website.md | 124 + .../controlling-exports-cover-image.jpg | Bin 0 -> 45081 bytes .../ing-open-sources-lion-side-by-side.png | Bin .../introducing-lions-website-cover-image.jpg | Bin 0 -> 15074 bytes docs/blog/index.md | 14 + .../blog/ing-open-sources-lion.md | 27 +- docs/blog/introducing-lions-website.md | 110 + docs/browserconfig.xml | 9 + docs/components/content/accordion/features.md | 214 + docs/components/content/accordion/index.md | 3 + docs/components/content/accordion/overview.md | 52 + .../collapsible/assets}/CustomCollapsible.js | 14 +- .../assets}/applyDemoCollapsibleStyles.js | 0 .../content/collapsible/examples.md | 83 + .../content/collapsible/features.md | 79 + docs/components/content/collapsible/index.md | 3 + .../content/collapsible/overview.md | 39 + docs/components/content/index.md | 1 + .../assets/custom-progress-indicator.js | 28 +- .../content/progress-indicator/examples.md | 76 + .../content/progress-indicator/index.md | 3 + .../content/progress-indicator/overview.md | 29 + docs/components/content/tabs/examples.md | 23 + docs/components/content/tabs/features.md | 194 + docs/components/content/tabs/index.md | 3 + docs/components/content/tabs/overview.md | 48 + .../content/tabs/src/lea-tab-panel.js | 2 + .../components/content/tabs/src/lea-tab.js | 2 + .../components/content/tabs/src/lea-tabs.js | 2 + .../icons/icon/assets}/bugs/bug01.svg.js | 0 .../icons/icon/assets}/bugs/bug02.svg.js | 0 .../icons/icon/assets}/bugs/bug05.svg.js | 0 .../icons/icon/assets}/bugs/bug06.svg.js | 0 .../icons/icon/assets}/bugs/bug08.svg.js | 0 .../icons/icon/assets}/bugs/bug12.svg.js | 0 .../icons/icon/assets}/bugs/bug19.svg.js | 0 .../icons/icon/assets}/bugs/bug23.svg.js | 0 .../icons/icon/assets}/bugs/bug24.svg.js | 0 .../icons/icon/assets}/iconset-bugs.js | 0 .../icons/icon/assets}/iconset-misc.js | 0 .../icons/icon/assets}/iconset-space.js | 0 .../icons/icon/assets}/misc/arrowLeft.svg.js | 0 .../assets}/space/aliens-spaceship.svg.js | 0 .../icons/icon/assets}/space/meteor.svg.js | 0 .../icons/icon/assets}/space/moon-flag.svg.js | 0 .../icons/icon/assets}/space/moon.svg.js | 0 .../icons/icon/assets}/space/night.svg.js | 0 .../icons/icon/assets}/space/orbit.svg.js | 0 .../icons/icon/assets}/space/planet.svg.js | 0 .../icons/icon/assets}/space/robot.svg.js | 0 .../icons/icon/assets}/space/rocket.svg.js | 0 .../icons/icon/assets}/space/satellite.svg.js | 0 .../icons/icon/assets}/space/signal.svg.js | 0 .../icon/assets}/space/space-helmet.svg.js | 0 .../icons/icon/assets}/space/sun.svg.js | 0 .../icons/icon/assets}/space/telescope.svg.js | 0 docs/components/icons/icon/features.md | 93 + docs/components/icons/icon/index.md | 3 + docs/components/icons/icon/overview.md | 40 + docs/components/icons/index.md | 1 + docs/components/index.md | 16 + docs/components/inputs/calendar/features.md | 192 + docs/components/inputs/calendar/index.md | 3 + docs/components/inputs/calendar/overview.md | 49 + .../inputs/checkbox-group/features.md | 205 + .../components/inputs/checkbox-group/index.md | 3 + .../inputs/checkbox-group/overview.md | 38 + docs/components/inputs/combobox/examples.md | 77 + docs/components/inputs/combobox/features.md | 253 + docs/components/inputs/combobox/index.md | 3 + docs/components/inputs/combobox/overview.md | 47 + .../inputs/combobox/src}/LinkMixin.js | 5 +- .../combobox/src}/demo-selection-display.js | 4 +- .../combobox/src}/gh-combobox/gh-button.js | 5 - .../combobox/src}/gh-combobox/gh-combobox.js | 2 +- .../inputs/combobox/src}/lazyRender.js | 0 .../inputs/combobox/src}/levenshtein.js | 0 .../combobox/src}/md-combobox/MdFieldMixin.js | 0 .../combobox/src}/md-combobox/md-combobox.js | 2 +- .../combobox/src}/md-combobox/md-input.js | 0 .../src}/md-combobox/style/load-roboto.js | 0 .../src}/md-combobox/style/md-ripple.js | 0 .../combobox/src}/wa-combobox/wa-combobox.js | 79 +- .../components/inputs/fieldset/features.md | 19 +- docs/components/inputs/fieldset/index.md | 3 + docs/components/inputs/fieldset/overview.md | 49 + docs/components/inputs/form/features.md | 73 + docs/components/inputs/form/index.md | 3 + docs/components/inputs/form/overview.md | 43 + docs/components/inputs/index.md | 1 + .../inputs/input-amount/features.md | 101 + docs/components/inputs/input-amount/index.md | 3 + .../inputs/input-amount/overview.md | 49 + docs/components/inputs/input-date/features.md | 83 + docs/components/inputs/input-date/index.md | 3 + docs/components/inputs/input-date/overview.md | 39 + .../inputs/input-datepicker/features.md | 78 + .../inputs/input-datepicker/index.md | 3 + .../inputs/input-datepicker/overview.md | 42 + .../components/inputs/input-email/features.md | 48 + docs/components/inputs/input-email/index.md | 3 + .../components/inputs/input-email/overview.md | 32 + docs/components/inputs/input-iban/features.md | 78 + docs/components/inputs/input-iban/index.md | 3 + docs/components/inputs/input-iban/overview.md | 37 + .../components/inputs/input-range/features.md | 70 + docs/components/inputs/input-range/index.md | 3 + .../components/inputs/input-range/overview.md | 35 + .../inputs/input-stepper/features.md | 41 + docs/components/inputs/input-stepper/index.md | 3 + .../inputs/input-stepper/overview.md | 36 + docs/components/inputs/input/features.md | 64 + docs/components/inputs/input/index.md | 3 + docs/components/inputs/input/overview.md | 36 + docs/components/inputs/listbox/features.md | 146 + docs/components/inputs/listbox/index.md | 3 + docs/components/inputs/listbox/overview.md | 40 + .../inputs/listbox/src/listboxData.js | 65 + docs/components/inputs/overview.md | 82 + .../components/inputs/radio-group/features.md | 114 + docs/components/inputs/radio-group/index.md | 3 + .../components/inputs/radio-group/overview.md | 44 + .../components/inputs/select-rich/features.md | 357 ++ docs/components/inputs/select-rich/index.md | 3 + .../components/inputs/select-rich/overview.md | 48 + docs/components/inputs/select/features.md | 55 + docs/components/inputs/select/index.md | 3 + docs/components/inputs/select/overview.md | 46 + docs/components/inputs/textarea/features.md | 95 + docs/components/inputs/textarea/index.md | 3 + docs/components/inputs/textarea/overview.md | 35 + .../components/interaction/button/examples.md | 30 + .../components/interaction/button/features.md | 99 + docs/components/interaction/button/index.md | 3 + .../components/interaction/button/overview.md | 30 + .../interaction/button/src/icon.svg.js | 5 + .../components/interaction/dialog/features.md | 154 + docs/components/interaction/dialog/index.md | 3 + .../components/interaction/dialog/overview.md | 63 + .../dialog/src/demo-dialog-style.js | 3 + .../interaction/dialog/src/demoStyle.js | 9 +- .../dialog/src/slots-dialog-content.js | 32 + .../dialog/src}/styled-dialog-content.js | 0 docs/components/interaction/index.md | 1 + .../components/interaction/switch/features.md | 75 + docs/components/interaction/switch/index.md | 3 + .../components/interaction/switch/overview.md | 30 + .../interaction/tooltip/examples.md | 39 + .../interaction/tooltip/features.md | 208 + docs/components/interaction/tooltip/index.md | 3 + .../interaction/tooltip/overview.md | 44 + docs/components/navigation/index.md | 1 + .../navigation/pagination/features.md | 101 + .../components/navigation/pagination/index.md | 3 + .../navigation/pagination/overview.md | 29 + docs/components/navigation/steps/features.md | 163 + docs/components/navigation/steps/index.md | 3 + docs/components/navigation/steps/overview.md | 61 + docs/docs/index.md | 19 + .../babel-plugin-extend-docs/index.md | 1 + .../babel-plugin-extend-docs/overview.md | 224 + docs/docs/node-tools/index.md | 1 + .../LocalConfiguration.md | 62 + .../providence-analytics/QueryResult.md | 111 + .../providence-analytics/analyzer.md | 69 + .../assets}/_mermaid.svg.js | 8 +- .../assets}/analyzer-query.gif | Bin .../assets}/feature-query.gif | Bin .../providence-analytics/assets}/provicli.gif | Bin .../assets}/providash.gif | Bin .../providence-analytics/dashboard.md | 24 + .../node-tools/providence-analytics/index.md | 1 + .../providence-analytics/overview.md | 188 + docs/docs/node-tools/publish-docs/index.md | 1 + docs/docs/node-tools/publish-docs/overview.md | 136 + docs/docs/node-tools/remark-extend/index.md | 1 + .../docs/node-tools/remark-extend/overview.md | 259 + docs/docs/rationales/index.md | 1 + .../docs/rationales/side-effects.md | 8 +- docs/docs/systems/core/index.md | 3 + docs/docs/systems/core/overview.md | 84 + .../form/assets}/FormatMixinDiagram-1.svg | 0 .../form/assets}/FormatMixinDiagram-2.svg | 0 .../form/assets}/FormatMixinDiagram-3.svg | 0 .../docs/systems/form/assets}/h-output.js | 0 .../docs/systems/form/features.md | 118 +- .../systems/form/formatting-and-parsing.md | 53 +- docs/docs/systems/form/index.md | 3 + .../docs/systems/form/interaction-states.md | 21 +- .../docs/systems/form/model-value.md | 12 +- docs/docs/systems/form/overview.md | 9 + docs/docs/systems/form/styling.md | 101 + .../docs/systems/form/validate.md | 622 ++- docs/docs/systems/icon/index.md | 3 + docs/docs/systems/icon/overview.md | 124 + docs/docs/systems/index.md | 1 + .../systems/localize/assets}/all-locales.js | 0 .../docs/systems/localize/assets}/en-AU.js | 0 .../docs/systems/localize/assets}/en-GB.js | 0 .../docs/systems/localize/assets}/en-US.js | 0 .../docs/systems/localize/assets}/en.js | 0 .../docs/systems/localize/assets}/nl-BE.js | 0 .../docs/systems/localize/assets}/nl-NL.js | 0 .../docs/systems/localize/assets}/nl.js | 0 .../docs/systems/localize/dates.md | 10 +- .../docs/systems/localize/features.md | 10 +- docs/docs/systems/localize/index.md | 3 + .../docs/systems/localize/numbers.md | 10 +- docs/docs/systems/localize/overview.md | 48 + .../docs/systems/localize/rationale.md | 12 +- docs/docs/systems/localize/text.md | 125 + .../assets}/applyDemoOverlayStyles.js | 5 +- .../overlays/assets}/demo-overlay-backdrop.js | 2 +- .../overlays/assets}/demo-overlay-system.js | 2 +- .../docs/systems/overlays/assets}/ref.js | 0 docs/docs/systems/overlays/configuration.md | 428 ++ .../docs/systems/overlays/features.md | 266 +- .../docs/systems/overlays/form-integration.md | 65 + docs/docs/systems/overlays/index.md | 3 + docs/docs/systems/overlays/overview.md | 119 + .../docs/systems/overlays/rationale.md | 10 +- .../docs/systems/overlays/scope.md | 120 +- .../docs/tools/ajax/assets}/naga.json | 0 .../docs/tools/ajax/assets}/pabu.json | 0 docs/docs/tools/ajax/features.md | 440 ++ docs/docs/tools/ajax/index.md | 3 + docs/docs/tools/ajax/overview.md | 49 + .../docs/tools/helpers/action-logger.md | 56 +- docs/docs/tools/helpers/index.md | 3 + docs/docs/tools/helpers/overview.md | 30 + docs/docs/tools/index.md | 1 + docs/docs/tools/singleton-manager/.gitignore | 1 + .../example-complex}/demo-app.js | 0 .../example-complex/index.md | 21 + .../node_modules/overlays/index.js | 3 +- .../node_modules/overlays/instance.js | 2 +- .../node_modules/overlays/package.json | 0 .../node_modules/page-a/package.json | 0 .../node_modules/page-a/page-a.js | 0 .../page-b/node_modules/overlays/index.js | 3 +- .../page-b/node_modules/overlays/instance.js | 2 +- .../page-b/node_modules/overlays/package.json | 0 .../node_modules/page-b/package.json | 0 .../node_modules/page-b/page-b.js | 0 .../example-complex}/overlayCompatibility.js | 2 +- .../example-complex}/package.json | 0 .../example-fail}/demo-app.js | 0 .../singleton-manager/example-fail/index.md | 19 + .../node_modules/overlays/index.js | 5 +- .../node_modules/overlays/instance.js | 0 .../node_modules/overlays/package.json | 0 .../node_modules/page-a/package.json | 0 .../node_modules/page-a/page-a.js | 0 .../page-b/node_modules/overlays/index.js | 5 +- .../page-b/node_modules/overlays/instance.js | 0 .../page-b/node_modules/overlays/package.json | 0 .../node_modules/page-b/package.json | 0 .../node_modules/page-b/page-b.js | 0 .../example-fail}/package.json | 0 .../example-success}/demo-app.js | 0 .../example-success/index.md | 18 + .../node_modules/overlays/index.js | 3 +- .../node_modules/overlays/instance.js | 2 +- .../node_modules/overlays/package.json | 0 .../node_modules/page-a/package.json | 0 .../node_modules/page-a/page-a.js | 0 .../page-b/node_modules/overlays/index.js | 3 +- .../page-b/node_modules/overlays/instance.js | 2 +- .../page-b/node_modules/overlays/package.json | 0 .../node_modules/page-b/package.json | 0 .../node_modules/page-b/page-b.js | 0 .../example-success}/overlayCompatibility.js | 2 +- .../example-success}/package.json | 0 docs/docs/tools/singleton-manager/index.md | 3 + docs/docs/tools/singleton-manager/overview.md | 304 + docs/favicon.ico | Bin 0 -> 15086 bytes .../guides/how-to/creating-a-custom-field.md | 43 +- docs/guides/how-to/get-started.md | 75 + docs/guides/how-to/index.md | 1 + docs/guides/index.md | 33 + .../principles/definitions-and-terms.md | 41 + docs/guides/principles/index.md | 1 + .../guides/principles/scoped-elements.md | 16 +- docs/guides/principles/styling.md | 32 + .../guides/principles/subclasser-apis.md | 10 +- docs/index.md | 29 + docs/intros/intros-buttons.md | 22 - docs/intros/intros-icon.md | 17 - docs/intros/intros-navigation.md | 22 - docs/intros/intros-others.md | 18 - docs/webmanifest.json | 29 + package.json | 29 +- packages-node/providence-analytics/README.md | 209 +- .../providence-analytics/docs/Analyzer.md | 90 +- .../providence-analytics/docs/Dashboard.md | 31 +- .../docs/LocalConfiguration.md | 70 +- .../providence-analytics/docs/QueryResult.md | 119 +- .../providence-analytics/docs/overview.md | 3 + .../providence-analytics/package.json | 5 +- packages-node/publish-docs/README.md | 3 + packages-node/publish-docs/docs/overview.md | 3 + packages-node/publish-docs/index.js | 3 + packages-node/publish-docs/package.json | 45 + packages-node/publish-docs/src/PublishDocs.js | 178 + .../publish-docs/src/PublishDocsCli.js | 49 + packages-node/publish-docs/src/cli.js | 6 + packages-node/publish-docs/src/listFiles.js | 35 + .../test-node/PublishDocs.test.js | 82 + .../adjust-links/docs/green/details.md | 1 + .../adjust-links/docs/green/overview.md | 3 + .../fixtures/adjust-links/docs/red/details.md | 1 + .../adjust-links/docs/red/overview.md | 7 + .../adjust-links/packages/my-pkg/README.md | 3 + .../packages/my-pkg/docs/details.md | 3 + .../packages/my-pkg/docs/overview.md | 3 + .../copies-assets/docs/green/green-data.json | 1 + .../copies-assets/docs/green/overview.md | 1 + .../docs/red/assets/more/red-data.json | 3 + .../docs/red/assets/red-data.json | 3 + .../copies-assets/docs/red/overview.md | 1 + .../copies-assets/packages/my-pkg/README.md | 3 + .../packages/my-pkg/docs/overview.md | 3 + .../fixtures/imports-md/docs/overview.md | 1 + .../imports-md/packages/my-pkg/README.md | 3 + .../fixtures/uses-commit-sha/docs/details.md | 1 + .../fixtures/uses-commit-sha/docs/overview.md | 3 + .../uses-commit-sha/packages/my-pkg/README.md | 3 + .../packages/my-pkg/docs/details.md | 3 + .../packages/my-pkg/docs/overview.md | 3 + .../publish-docs/test-node/test-helpers.js | 47 + packages/accordion/README.md | 264 +- packages/accordion/docs/features.md | 3 + packages/accordion/docs/overview.md | 3 + packages/accordion/package.json | 8 +- packages/ajax/README.md | 467 +- packages/ajax/docs/features.md | 3 + packages/ajax/docs/overview.md | 3 + packages/ajax/package.json | 10 +- packages/button/README.md | 163 +- packages/button/docs/features.md | 3 + packages/button/docs/overview.md | 3 + packages/button/package.json | 8 +- packages/button/test/lion-button.test.js | 2 +- packages/calendar/README.md | 221 +- packages/calendar/docs/features.md | 3 + packages/calendar/docs/overview.md | 3 + packages/calendar/package.json | 11 +- packages/calendar/src/LionCalendar.js | 32 +- packages/calendar/test-helpers/index.js | 3 + packages/calendar/test/lion-calendar.test.js | 4 +- packages/checkbox-group/README.md | 248 +- packages/checkbox-group/define.js | 3 + packages/checkbox-group/docs/features.md | 3 + packages/checkbox-group/docs/overview.md | 3 + packages/checkbox-group/package.json | 13 +- .../lion-checkbox-group-integrations.test.js | 5 +- .../test/lion-checkbox-group.test.js | 3 +- ...heckbox-indeterminate-integrations.test.js | 4 +- .../test/lion-checkbox-indeterminate.test.js | 4 +- .../test/lion-checkbox-integrations.test.js | 4 +- .../checkbox-group/test/lion-checkbox.test.js | 2 +- packages/collapsible/README.md | 210 +- .../collapsible/demo/custom-collapsible.js | 3 - packages/collapsible/docs/features.md | 3 + packages/collapsible/docs/overview.md | 3 + packages/collapsible/package.json | 8 +- .../collapsible/test/lion-collapsible.test.js | 2 +- packages/combobox/README.md | 290 +- packages/combobox/docs/features.md | 3 + .../docs/google-combobox/assets/appleLogo.png | Bin 2225 -> 0 bytes .../assets/google-clear-icon.js | 9 - .../assets/google-search-icon.js | 9 - .../assets/google-voice-search-icon.js | 19 - .../assets/googlelogo_color_272x92dp.png | Bin 5969 -> 0 bytes packages/combobox/docs/overview.md | 3 + packages/combobox/package.json | 8 +- .../test/lion-combobox-integrations.test.js | 4 +- packages/combobox/test/lion-combobox.test.js | 4 +- packages/core/README.md | 12 +- .../guidelines/10-guidelines-definitions.md | 63 - .../docs/guidelines/20-guidelines-styling.md | 46 - .../guides/how-to/creating-a-custom-field.md | 3 + .../core/docs/guides/how-to/get-started.md | 3 + packages/core/docs/guides/how-to/index.md | 3 + packages/core/docs/guides/index.md | 3 + .../principles/definitions-and-terms.md | 3 + packages/core/docs/guides/principles/index.md | 3 + .../docs/guides/principles/scoped-elements.md | 3 + .../core/docs/guides/principles/styling.md | 3 + .../docs/guides/principles/subclasser-apis.md | 3 + packages/core/docs/overview.md | 3 + packages/core/docs/rationales/side-effects.md | 3 + packages/core/package.json | 10 +- packages/core/test-helpers/index.js | 1 + packages/dialog/README.md | 215 +- packages/dialog/docs/features.md | 3 + packages/dialog/docs/overview.md | 3 + packages/dialog/docs/slots-dialog-content.js | 14 - packages/dialog/package.json | 8 +- packages/dialog/test/lion-dialog.test.js | 4 +- packages/fieldset/README.md | 68 +- packages/fieldset/docs/features.md | 3 + packages/fieldset/docs/overview.md | 3 + packages/fieldset/package.json | 8 +- packages/fieldset/test/lion-fieldset.test.js | 6 +- packages/form-core/README.md | 62 +- packages/form-core/define.js | 2 + .../form-core/docs/choice-group/README.md | 22 - packages/form-core/docs/overview.md | 3 + packages/form-core/docs/validate/README.md | 137 - .../docs/validate/assets/FlowDiagram.md | 17 - packages/form-core/docs/validate/system.md | 221 - packages/form-core/package.json | 16 +- packages/form-core/test-helpers/index.js | 1 + .../choice-group/ChoiceGroupMixin.suite.js | 2 +- .../form-group/FormGroupMixin-input.suite.js | 2 +- .../form-group/FormGroupMixin.suite.js | 2 +- packages/form-core/test-suites/index.js | 9 + .../choice-group/ChoiceGroupMixin.test.js | 2 +- packages/form-core/test/lion-field.test.js | 2 +- .../validate/lion-validation-feedback.test.js | 2 +- packages/form-integrations/README.md | 42 +- .../docs/20-system-overview.md | 97 - .../docs/50-content-inside-fields.md | 25 - .../docs/60-dialog-integration.md | 61 - packages/form-integrations/docs/features.md | 3 + .../docs/formatting-and-parsing.md | 3 + .../docs/interaction-state.md | 3 + .../form-integrations/docs/model-value.md | 3 + packages/form-integrations/docs/overview.md | 3 + packages/form-integrations/docs/styling.md | 3 + packages/form-integrations/docs/validate.md | 3 + packages/form-integrations/package.json | 10 +- .../form-integrations/test/form-reset.test.js | 30 +- .../test/helpers/umbrella-form.js | 34 +- .../test/model-value-consistency.test.js | 37 +- .../test/model-value-event.test.js | 4 +- packages/form/README.md | 42 +- packages/form/docs/features.md | 3 + packages/form/docs/overview.md | 3 + packages/form/package.json | 8 +- packages/form/test/lion-form.test.js | 6 +- packages/helpers/README.md | 39 +- packages/helpers/define.js | 2 + packages/helpers/docs/action-logger.md | 3 + packages/helpers/docs/overview.md | 3 + packages/helpers/package.json | 11 +- .../test/sb-action-logger.test.js | 2 +- packages/icon/README.md | 120 +- packages/icon/docs/features.md | 3 + packages/icon/docs/overview.md | 3 + packages/icon/docs/system.md | 131 +- packages/icon/package.json | 8 +- packages/icon/test/lion-icon.test.js | 2 +- packages/input-amount/README.md | 150 +- packages/input-amount/docs/features.md | 3 + packages/input-amount/docs/overview.md | 3 + packages/input-amount/package.json | 8 +- .../lion-input-amount-integrations.test.js | 6 +- .../test/lion-input-amount.test.js | 2 +- packages/input-date/README.md | 116 +- packages/input-date/docs/features.md | 3 + packages/input-date/docs/overview.md | 3 + packages/input-date/package.json | 8 +- .../test/lion-input-date-integrations.test.js | 6 +- .../input-date/test/lion-input-date.test.js | 2 +- packages/input-datepicker/README.md | 127 +- packages/input-datepicker/docs/features.md | 3 + packages/input-datepicker/docs/overview.md | 3 + packages/input-datepicker/package.json | 11 +- .../src/LionInputDatepicker.js | 68 +- ...lion-input-datepicker-integrations.test.js | 6 +- .../test/lion-input-datepicker.test.js | 4 +- packages/input-email/README.md | 86 +- packages/input-email/docs/features.md | 3 + packages/input-email/docs/overview.md | 3 + packages/input-email/package.json | 8 +- .../lion-input-email-integrations.test.js | 4 +- .../input-email/test/lion-input-email.test.js | 2 +- packages/input-iban/README.md | 117 +- packages/input-iban/docs/features.md | 3 + packages/input-iban/docs/overview.md | 3 + packages/input-iban/package.json | 9 +- packages/input-iban/src/validators.js | 68 +- .../test/lion-input-iban-integrations.test.js | 4 +- .../input-iban/test/lion-input-iban.test.js | 2 +- packages/input-iban/test/validators.test.js | 2 +- packages/input-range/README.md | 109 +- packages/input-range/docs/features.md | 3 + packages/input-range/docs/overview.md | 3 + packages/input-range/package.json | 8 +- .../input-range/test/lion-input-range.test.js | 2 +- packages/input-stepper/README.md | 89 +- packages/input-stepper/docs/features.md | 3 + packages/input-stepper/docs/overview.md | 3 + packages/input-stepper/package.json | 8 +- .../test/lion-input-stepper.test.js | 2 +- packages/input/README.md | 178 +- packages/input/docs/features.md | 3 + packages/input/docs/overview.md | 3 + packages/input/package.json | 8 +- .../input/test/input-integrations.test.js | 4 +- .../test/lion-input-integrations.test.js | 6 +- packages/input/test/lion-input.test.js | 2 +- packages/listbox/README.md | 186 +- packages/listbox/define.js | 3 + packages/listbox/docs/features.md | 3 + packages/listbox/docs/overview.md | 3 + packages/listbox/package.json | 16 +- .../listbox/test-suites/ListboxMixin.suite.js | 4 +- packages/listbox/test-suites/index.js | 1 + packages/listbox/test/lion-option.test.js | 2 +- packages/listbox/test/lion-options.test.js | 2 +- packages/localize/README.md | 59 +- packages/localize/_docs/amount-html.md | 32 - packages/localize/_docs/date.md | 35 - packages/localize/_docs/message.md | 187 - packages/localize/_docs/number.md | 31 - .../localize/docs/10-features-overview.md | 157 - .../docs/40-google-translate-integration.md | 43 - packages/localize/docs/dates.md | 3 + packages/localize/docs/features.md | 3 + packages/localize/docs/numbers.md | 3 + packages/localize/docs/overview.md | 3 + packages/localize/docs/rationale.md | 3 + packages/localize/docs/text.md | 3 + packages/localize/package.json | 8 +- packages/localize/test-helpers.js | 7 - packages/localize/test-helpers/index.js | 7 + .../localize/test/LocalizeManager.test.js | 2 +- packages/localize/test/LocalizeMixin.test.js | 2 +- .../localize/test/date/formatDate.test.js | 2 +- .../date/getDateFormatBasedOnLocale.test.js | 2 +- packages/localize/test/date/parseDate.test.js | 2 +- .../localize/test/number/formatNumber.test.js | 2 +- .../test/number/formatNumberToParts.test.js | 2 +- .../test/number/getCurrencyName.test.js | 2 +- packages/overlays/README.md | 130 +- .../overlays/docs/40-system-configuration.md | 405 -- packages/overlays/docs/configuration.md | 3 + packages/overlays/docs/features.md | 3 + packages/overlays/docs/form-integration.md | 3 + packages/overlays/docs/overview.md | 3 + packages/overlays/docs/rationale.md | 3 + packages/overlays/docs/scope.md | 3 + packages/overlays/package.json | 8 +- packages/overlays/test-suites/index.js | 1 + packages/pagination/README.md | 140 +- packages/pagination/docs/features.md | 3 + packages/pagination/docs/overview.md | 3 + packages/pagination/package.json | 9 +- packages/pagination/src/LionPagination.js | 32 +- .../pagination/test/lion-pagination.test.js | 2 +- packages/progress-indicator/README.md | 91 +- .../demo/custom-progress-indicator.js | 3 - packages/progress-indicator/docs/overview.md | 3 + packages/progress-indicator/package.json | 9 +- .../src/LionProgressIndicator.js | 32 +- .../test/lion-progress-indicator.test.js | 2 +- packages/radio-group/README.md | 163 +- packages/radio-group/define.js | 2 + packages/radio-group/docs/features.md | 3 + packages/radio-group/docs/overview.md | 3 + packages/radio-group/package.json | 12 +- .../lion-radio-group-integrations.test.js | 5 +- .../radio-group/test/lion-radio-group.test.js | 3 +- .../test/lion-radio-integrations.test.js | 4 +- packages/radio-group/test/lion-radio.test.js | 2 +- packages/select-rich/README.md | 409 +- packages/select-rich/define.js | 4 + packages/select-rich/docs/features.md | 3 + packages/select-rich/docs/overview.md | 3 + packages/select-rich/lion-option.js | 2 +- packages/select-rich/lion-options.js | 2 +- packages/select-rich/package.json | 18 +- .../test/lion-select-invoker.test.js | 2 +- ...n-select-listbox-suite-integration.test.js | 4 +- ...ion-select-rich-dialog-integration.test.js | 5 +- .../test/lion-select-rich-interaction.test.js | 5 +- .../select-rich/test/lion-select-rich.test.js | 7 +- packages/select/README.md | 105 +- packages/select/docs/features.md | 3 + packages/select/docs/overview.md | 3 + packages/select/package.json | 8 +- packages/select/test/lion-select.test.js | 2 +- packages/singleton-manager/README.md | 308 +- .../singleton-manager/demo/fail/index.html | 11 - .../singleton-manager/demo/fail/server.js | 6 - .../demo/singleton-complex/index.html | 11 - .../demo/singleton-complex/server.js | 6 - .../demo/singleton/index.html | 11 - .../demo/singleton/server.js | 6 - packages/singleton-manager/docs/overview.md | 3 + packages/singleton-manager/package.json | 10 +- .../test/SingletonManagerClass.test.js | 2 +- .../test/singleton-demo.test.js | 15 - packages/steps/README.md | 210 +- packages/steps/define.js | 2 + packages/steps/docs/features.md | 3 + packages/steps/docs/overview.md | 3 + packages/steps/package.json | 12 +- .../refactorToStorybook/complex-demo-app.html | 4 +- packages/steps/test/lion-step.test.js | 2 +- packages/steps/test/lion-steps.test.js | 3 +- packages/switch/README.md | 113 +- packages/switch/define.js | 2 + packages/switch/docs/features.md | 3 + packages/switch/docs/overview.md | 3 + packages/switch/package.json | 12 +- .../switch/test/lion-switch-button.test.js | 2 +- packages/switch/test/lion-switch.test.js | 2 +- packages/tabs/README.md | 257 +- packages/tabs/docs/features.md | 3 + packages/tabs/docs/overview.md | 3 + packages/tabs/package.json | 8 +- packages/tabs/test/lion-tabs.test.js | 2 +- packages/textarea/README.md | 134 +- packages/textarea/docs/features.md | 3 + packages/textarea/docs/overview.md | 3 + packages/textarea/package.json | 8 +- .../test/lion-textarea-integrations.test.js | 4 +- packages/textarea/test/lion-textarea.test.js | 2 +- packages/tooltip/README.md | 257 +- packages/tooltip/docs/features.md | 3 + packages/tooltip/docs/overview.md | 3 + packages/tooltip/package.json | 11 +- packages/tooltip/test/lion-tooltip.test.js | 4 +- packages/validate-messages/README.md | 3 + packages/validate-messages/docs/features.md | 3 + packages/validate-messages/docs/overview.md | 3 + packages/validate-messages/package.json | 11 +- .../src/loadDefaultFeedbackMessages.js | 68 +- rocket.config.mjs | 7 + yarn.lock | 4900 ++++++++++------- 670 files changed, 14455 insertions(+), 12288 deletions(-) create mode 100644 .changeset/early-dolphins-build.md create mode 100644 .changeset/famous-bears-confess.md create mode 100644 .changeset/odd-beds-clean.md create mode 100644 .changeset/silly-ants-melt.md create mode 100644 .eleventyignore delete mode 100644 .storybook/main.js delete mode 100644 .storybook/preview-head.html delete mode 100755 .storybook/preview.js create mode 100644 assets/logo.png delete mode 100644 demo/docs/20-lea-tabs.md delete mode 100644 demo/lea-tab-panel.js delete mode 100644 demo/lea-tab.js delete mode 100644 demo/lea-tabs.js create mode 100644 docs/404.md delete mode 100644 docs/README.md create mode 100644 docs/_assets/_static/icons/android-chrome-192x192.png create mode 100644 docs/_assets/_static/icons/android-chrome-512x512.png create mode 100644 docs/_assets/_static/icons/apple-touch-icon.png create mode 100644 docs/_assets/_static/icons/favicon-16x16.png create mode 100644 docs/_assets/_static/icons/favicon-32x32.png create mode 100644 docs/_assets/_static/icons/mstile-150x150.png create mode 100644 docs/_assets/_static/icons/safari-pinned-tab.svg create mode 100644 docs/_assets/logo.svg create mode 100644 docs/_assets/style.css create mode 100644 docs/_assets/variables.css create mode 100644 docs/_data/footer.json create mode 100644 docs/_data/site.cjs create mode 100644 docs/about/slack.md create mode 100644 docs/blog/controlling-exports.md rename docs/{ => blog}/extending-documentation.md (88%) create mode 100644 docs/blog/extending-lions-website.md create mode 100644 docs/blog/images/controlling-exports-cover-image.jpg rename demo/docs/assets/side-by-side.png => docs/blog/images/ing-open-sources-lion-side-by-side.png (100%) create mode 100644 docs/blog/images/introducing-lions-website-cover-image.jpg create mode 100644 docs/blog/index.md rename demo/README.md => docs/blog/ing-open-sources-lion.md (92%) create mode 100644 docs/blog/introducing-lions-website.md create mode 100644 docs/browserconfig.xml create mode 100644 docs/components/content/accordion/features.md create mode 100644 docs/components/content/accordion/index.md create mode 100644 docs/components/content/accordion/overview.md rename {packages/collapsible/demo => docs/components/content/collapsible/assets}/CustomCollapsible.js (88%) rename {packages/collapsible/demo => docs/components/content/collapsible/assets}/applyDemoCollapsibleStyles.js (100%) create mode 100644 docs/components/content/collapsible/examples.md create mode 100644 docs/components/content/collapsible/features.md create mode 100644 docs/components/content/collapsible/index.md create mode 100644 docs/components/content/collapsible/overview.md create mode 100644 docs/components/content/index.md rename packages/progress-indicator/demo/CustomProgressIndicator.js => docs/components/content/progress-indicator/assets/custom-progress-indicator.js (65%) create mode 100644 docs/components/content/progress-indicator/examples.md create mode 100644 docs/components/content/progress-indicator/index.md create mode 100644 docs/components/content/progress-indicator/overview.md create mode 100644 docs/components/content/tabs/examples.md create mode 100644 docs/components/content/tabs/features.md create mode 100644 docs/components/content/tabs/index.md create mode 100644 docs/components/content/tabs/overview.md rename demo/src/LeaTabPanel.js => docs/components/content/tabs/src/lea-tab-panel.js (89%) rename demo/src/LeaTab.js => docs/components/content/tabs/src/lea-tab.js (96%) rename demo/src/LeaTabs.js => docs/components/content/tabs/src/lea-tabs.js (90%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug01.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug02.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug05.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug06.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug08.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug12.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug19.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug23.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/bugs/bug24.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/iconset-bugs.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/iconset-misc.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/iconset-space.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/misc/arrowLeft.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/aliens-spaceship.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/meteor.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/moon-flag.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/moon.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/night.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/orbit.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/planet.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/robot.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/rocket.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/satellite.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/signal.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/space-helmet.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/sun.svg.js (100%) rename {packages/icon/docs/icons => docs/components/icons/icon/assets}/space/telescope.svg.js (100%) create mode 100644 docs/components/icons/icon/features.md create mode 100644 docs/components/icons/icon/index.md create mode 100644 docs/components/icons/icon/overview.md create mode 100644 docs/components/icons/index.md create mode 100644 docs/components/index.md create mode 100644 docs/components/inputs/calendar/features.md create mode 100644 docs/components/inputs/calendar/index.md create mode 100644 docs/components/inputs/calendar/overview.md create mode 100644 docs/components/inputs/checkbox-group/features.md create mode 100644 docs/components/inputs/checkbox-group/index.md create mode 100644 docs/components/inputs/checkbox-group/overview.md create mode 100644 docs/components/inputs/combobox/examples.md create mode 100644 docs/components/inputs/combobox/features.md create mode 100644 docs/components/inputs/combobox/index.md create mode 100644 docs/components/inputs/combobox/overview.md rename {packages/combobox/docs => docs/components/inputs/combobox/src}/LinkMixin.js (90%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/demo-selection-display.js (97%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/gh-combobox/gh-button.js (96%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/gh-combobox/gh-combobox.js (99%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/lazyRender.js (100%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/levenshtein.js (100%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/md-combobox/MdFieldMixin.js (100%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/md-combobox/md-combobox.js (97%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/md-combobox/md-input.js (100%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/md-combobox/style/load-roboto.js (100%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/md-combobox/style/md-ripple.js (100%) rename {packages/combobox/docs => docs/components/inputs/combobox/src}/wa-combobox/wa-combobox.js (84%) rename packages/form-integrations/docs/fieldset-examples.md => docs/components/inputs/fieldset/features.md (93%) create mode 100644 docs/components/inputs/fieldset/index.md create mode 100644 docs/components/inputs/fieldset/overview.md create mode 100644 docs/components/inputs/form/features.md create mode 100644 docs/components/inputs/form/index.md create mode 100644 docs/components/inputs/form/overview.md create mode 100644 docs/components/inputs/index.md create mode 100644 docs/components/inputs/input-amount/features.md create mode 100644 docs/components/inputs/input-amount/index.md create mode 100644 docs/components/inputs/input-amount/overview.md create mode 100644 docs/components/inputs/input-date/features.md create mode 100644 docs/components/inputs/input-date/index.md create mode 100644 docs/components/inputs/input-date/overview.md create mode 100644 docs/components/inputs/input-datepicker/features.md create mode 100644 docs/components/inputs/input-datepicker/index.md create mode 100644 docs/components/inputs/input-datepicker/overview.md create mode 100644 docs/components/inputs/input-email/features.md create mode 100644 docs/components/inputs/input-email/index.md create mode 100644 docs/components/inputs/input-email/overview.md create mode 100644 docs/components/inputs/input-iban/features.md create mode 100644 docs/components/inputs/input-iban/index.md create mode 100644 docs/components/inputs/input-iban/overview.md create mode 100644 docs/components/inputs/input-range/features.md create mode 100644 docs/components/inputs/input-range/index.md create mode 100644 docs/components/inputs/input-range/overview.md create mode 100644 docs/components/inputs/input-stepper/features.md create mode 100644 docs/components/inputs/input-stepper/index.md create mode 100644 docs/components/inputs/input-stepper/overview.md create mode 100644 docs/components/inputs/input/features.md create mode 100644 docs/components/inputs/input/index.md create mode 100644 docs/components/inputs/input/overview.md create mode 100644 docs/components/inputs/listbox/features.md create mode 100644 docs/components/inputs/listbox/index.md create mode 100644 docs/components/inputs/listbox/overview.md create mode 100644 docs/components/inputs/listbox/src/listboxData.js create mode 100644 docs/components/inputs/overview.md create mode 100644 docs/components/inputs/radio-group/features.md create mode 100644 docs/components/inputs/radio-group/index.md create mode 100644 docs/components/inputs/radio-group/overview.md create mode 100644 docs/components/inputs/select-rich/features.md create mode 100644 docs/components/inputs/select-rich/index.md create mode 100644 docs/components/inputs/select-rich/overview.md create mode 100644 docs/components/inputs/select/features.md create mode 100644 docs/components/inputs/select/index.md create mode 100644 docs/components/inputs/select/overview.md create mode 100644 docs/components/inputs/textarea/features.md create mode 100644 docs/components/inputs/textarea/index.md create mode 100644 docs/components/inputs/textarea/overview.md create mode 100644 docs/components/interaction/button/examples.md create mode 100644 docs/components/interaction/button/features.md create mode 100644 docs/components/interaction/button/index.md create mode 100644 docs/components/interaction/button/overview.md create mode 100644 docs/components/interaction/button/src/icon.svg.js create mode 100644 docs/components/interaction/dialog/features.md create mode 100644 docs/components/interaction/dialog/index.md create mode 100644 docs/components/interaction/dialog/overview.md create mode 100644 docs/components/interaction/dialog/src/demo-dialog-style.js rename packages/dialog/docs/demo-dialog-style.js => docs/components/interaction/dialog/src/demoStyle.js (92%) create mode 100644 docs/components/interaction/dialog/src/slots-dialog-content.js rename {packages/dialog/docs => docs/components/interaction/dialog/src}/styled-dialog-content.js (100%) create mode 100644 docs/components/interaction/index.md create mode 100644 docs/components/interaction/switch/features.md create mode 100644 docs/components/interaction/switch/index.md create mode 100644 docs/components/interaction/switch/overview.md create mode 100644 docs/components/interaction/tooltip/examples.md create mode 100644 docs/components/interaction/tooltip/features.md create mode 100644 docs/components/interaction/tooltip/index.md create mode 100644 docs/components/interaction/tooltip/overview.md create mode 100644 docs/components/navigation/index.md create mode 100644 docs/components/navigation/pagination/features.md create mode 100644 docs/components/navigation/pagination/index.md create mode 100644 docs/components/navigation/pagination/overview.md create mode 100644 docs/components/navigation/steps/features.md create mode 100644 docs/components/navigation/steps/index.md create mode 100644 docs/components/navigation/steps/overview.md create mode 100644 docs/docs/index.md create mode 100644 docs/docs/node-tools/babel-plugin-extend-docs/index.md create mode 100644 docs/docs/node-tools/babel-plugin-extend-docs/overview.md create mode 100644 docs/docs/node-tools/index.md create mode 100644 docs/docs/node-tools/providence-analytics/LocalConfiguration.md create mode 100644 docs/docs/node-tools/providence-analytics/QueryResult.md create mode 100644 docs/docs/node-tools/providence-analytics/analyzer.md rename {packages-node/providence-analytics/docs => docs/docs/node-tools/providence-analytics/assets}/_mermaid.svg.js (99%) rename {packages-node/providence-analytics/dev-assets => docs/docs/node-tools/providence-analytics/assets}/analyzer-query.gif (100%) rename {packages-node/providence-analytics/dev-assets => docs/docs/node-tools/providence-analytics/assets}/feature-query.gif (100%) rename {packages-node/providence-analytics/dev-assets => docs/docs/node-tools/providence-analytics/assets}/provicli.gif (100%) rename {packages-node/providence-analytics/dev-assets => docs/docs/node-tools/providence-analytics/assets}/providash.gif (100%) create mode 100644 docs/docs/node-tools/providence-analytics/dashboard.md create mode 100644 docs/docs/node-tools/providence-analytics/index.md create mode 100644 docs/docs/node-tools/providence-analytics/overview.md create mode 100644 docs/docs/node-tools/publish-docs/index.md create mode 100644 docs/docs/node-tools/publish-docs/overview.md create mode 100644 docs/docs/node-tools/remark-extend/index.md create mode 100644 docs/docs/node-tools/remark-extend/overview.md create mode 100644 docs/docs/rationales/index.md rename packages/core/docs/rationales/001-side-effects.md => docs/docs/rationales/side-effects.md (99%) create mode 100644 docs/docs/systems/core/index.md create mode 100644 docs/docs/systems/core/overview.md rename {packages/form-integrations/dev-assets => docs/docs/systems/form/assets}/FormatMixinDiagram-1.svg (100%) rename {packages/form-integrations/dev-assets => docs/docs/systems/form/assets}/FormatMixinDiagram-2.svg (100%) rename {packages/form-integrations/dev-assets => docs/docs/systems/form/assets}/FormatMixinDiagram-3.svg (100%) rename {packages/form-integrations/docs/helper-wc => docs/docs/systems/form/assets}/h-output.js (100%) rename packages/form-integrations/docs/15-features-overview.md => docs/docs/systems/form/features.md (62%) rename packages/form-integrations/docs/30-system-formatting.md => docs/docs/systems/form/formatting-and-parsing.md (79%) create mode 100644 docs/docs/systems/form/index.md rename packages/form-integrations/docs/35-system-interaction-states.md => docs/docs/systems/form/interaction-states.md (92%) rename packages/form-integrations/docs/25-system-model-value.md => docs/docs/systems/form/model-value.md (80%) create mode 100644 docs/docs/systems/form/overview.md create mode 100644 docs/docs/systems/form/styling.md rename packages/form-integrations/docs/17-validation-examples.md => docs/docs/systems/form/validate.md (59%) create mode 100644 docs/docs/systems/icon/index.md create mode 100644 docs/docs/systems/icon/overview.md create mode 100644 docs/docs/systems/index.md rename {packages/localize/docs => docs/docs/systems/localize/assets}/all-locales.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/en-AU.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/en-GB.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/en-US.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/en.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/nl-BE.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/nl-NL.js (100%) rename {packages/localize/docs/translations => docs/docs/systems/localize/assets}/nl.js (100%) rename packages/localize/docs/30-dates.md => docs/docs/systems/localize/dates.md (95%) rename packages/localize/docs/50-system-overview.md => docs/docs/systems/localize/features.md (96%) create mode 100644 docs/docs/systems/localize/index.md rename packages/localize/docs/20-numbers.md => docs/docs/systems/localize/numbers.md (96%) create mode 100644 docs/docs/systems/localize/overview.md rename packages/localize/docs/60-system-rationale.md => docs/docs/systems/localize/rationale.md (89%) create mode 100644 docs/docs/systems/localize/text.md rename {packages/overlays/docs => docs/docs/systems/overlays/assets}/applyDemoOverlayStyles.js (88%) rename {packages/overlays/docs => docs/docs/systems/overlays/assets}/demo-overlay-backdrop.js (97%) rename {packages/overlays/docs => docs/docs/systems/overlays/assets}/demo-overlay-system.js (94%) rename {packages/overlays/docs/directives => docs/docs/systems/overlays/assets}/ref.js (100%) create mode 100644 docs/docs/systems/overlays/configuration.md rename packages/overlays/docs/20-index.md => docs/docs/systems/overlays/features.md (76%) create mode 100644 docs/docs/systems/overlays/form-integration.md create mode 100644 docs/docs/systems/overlays/index.md create mode 100644 docs/docs/systems/overlays/overview.md rename packages/overlays/docs/30-system-rationale.md => docs/docs/systems/overlays/rationale.md (98%) rename packages/overlays/docs/OverlaySystemScope.md => docs/docs/systems/overlays/scope.md (58%) rename {packages/ajax/docs => docs/docs/tools/ajax/assets}/naga.json (100%) rename {packages/ajax/docs => docs/docs/tools/ajax/assets}/pabu.json (100%) create mode 100644 docs/docs/tools/ajax/features.md create mode 100644 docs/docs/tools/ajax/index.md create mode 100644 docs/docs/tools/ajax/overview.md rename packages/helpers/sb-action-logger/README.md => docs/docs/tools/helpers/action-logger.md (78%) create mode 100644 docs/docs/tools/helpers/index.md create mode 100644 docs/docs/tools/helpers/overview.md create mode 100644 docs/docs/tools/index.md create mode 100644 docs/docs/tools/singleton-manager/.gitignore rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/demo-app.js (100%) create mode 100644 docs/docs/tools/singleton-manager/example-complex/index.md rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-complex}/node_modules/overlays/index.js (86%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/node_modules/overlays/instance.js (71%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-complex}/node_modules/overlays/package.json (100%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-a/package.json (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-a/page-a.js (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-b/node_modules/overlays/index.js (86%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-b/node_modules/overlays/instance.js (69%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-b/node_modules/overlays/package.json (100%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-b/package.json (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/node_modules/page-b/page-b.js (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-complex}/overlayCompatibility.js (96%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-complex}/package.json (100%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-fail}/demo-app.js (100%) create mode 100644 docs/docs/tools/singleton-manager/example-fail/index.md rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-fail}/node_modules/overlays/index.js (77%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-fail}/node_modules/overlays/instance.js (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-fail}/node_modules/overlays/package.json (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-a/package.json (100%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-a/page-a.js (100%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-b/node_modules/overlays/index.js (78%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-b/node_modules/overlays/instance.js (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-b/node_modules/overlays/package.json (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-b/package.json (100%) rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-fail}/node_modules/page-b/page-b.js (100%) rename {packages/singleton-manager/demo/singleton-complex => docs/docs/tools/singleton-manager/example-fail}/package.json (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/demo-app.js (100%) create mode 100644 docs/docs/tools/singleton-manager/example-success/index.md rename {packages/singleton-manager/demo/fail => docs/docs/tools/singleton-manager/example-success}/node_modules/overlays/index.js (86%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/overlays/instance.js (71%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/overlays/package.json (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-a/package.json (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-a/page-a.js (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-b/node_modules/overlays/index.js (86%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-b/node_modules/overlays/instance.js (69%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-b/node_modules/overlays/package.json (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-b/package.json (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/node_modules/page-b/page-b.js (100%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/overlayCompatibility.js (90%) rename {packages/singleton-manager/demo/singleton => docs/docs/tools/singleton-manager/example-success}/package.json (100%) create mode 100644 docs/docs/tools/singleton-manager/index.md create mode 100644 docs/docs/tools/singleton-manager/overview.md create mode 100644 docs/favicon.ico rename packages/form-integrations/docs/40-system-creating-a-custom-field.md => docs/guides/how-to/creating-a-custom-field.md (56%) create mode 100644 docs/guides/how-to/get-started.md create mode 100644 docs/guides/how-to/index.md create mode 100644 docs/guides/index.md create mode 100644 docs/guides/principles/definitions-and-terms.md create mode 100644 docs/guides/principles/index.md rename packages/core/docs/guidelines/30-guidelines-scoped-elements.md => docs/guides/principles/scoped-elements.md (90%) create mode 100644 docs/guides/principles/styling.md rename packages/core/docs/guidelines/40-guidelines-subclasser-apis.md => docs/guides/principles/subclasser-apis.md (85%) create mode 100644 docs/index.md delete mode 100644 docs/intros/intros-buttons.md delete mode 100644 docs/intros/intros-icon.md delete mode 100644 docs/intros/intros-navigation.md delete mode 100644 docs/intros/intros-others.md create mode 100644 docs/webmanifest.json create mode 100644 packages-node/providence-analytics/docs/overview.md create mode 100644 packages-node/publish-docs/README.md create mode 100644 packages-node/publish-docs/docs/overview.md create mode 100644 packages-node/publish-docs/index.js create mode 100644 packages-node/publish-docs/package.json create mode 100644 packages-node/publish-docs/src/PublishDocs.js create mode 100644 packages-node/publish-docs/src/PublishDocsCli.js create mode 100755 packages-node/publish-docs/src/cli.js create mode 100644 packages-node/publish-docs/src/listFiles.js create mode 100644 packages-node/publish-docs/test-node/PublishDocs.test.js create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/docs/green/details.md create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/docs/green/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/docs/red/details.md create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/docs/red/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/packages/my-pkg/README.md create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/packages/my-pkg/docs/details.md create mode 100644 packages-node/publish-docs/test-node/fixtures/adjust-links/packages/my-pkg/docs/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/docs/green/green-data.json create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/docs/green/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/docs/red/assets/more/red-data.json create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/docs/red/assets/red-data.json create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/docs/red/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/packages/my-pkg/README.md create mode 100644 packages-node/publish-docs/test-node/fixtures/copies-assets/packages/my-pkg/docs/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/imports-md/docs/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/imports-md/packages/my-pkg/README.md create mode 100644 packages-node/publish-docs/test-node/fixtures/uses-commit-sha/docs/details.md create mode 100644 packages-node/publish-docs/test-node/fixtures/uses-commit-sha/docs/overview.md create mode 100644 packages-node/publish-docs/test-node/fixtures/uses-commit-sha/packages/my-pkg/README.md create mode 100644 packages-node/publish-docs/test-node/fixtures/uses-commit-sha/packages/my-pkg/docs/details.md create mode 100644 packages-node/publish-docs/test-node/fixtures/uses-commit-sha/packages/my-pkg/docs/overview.md create mode 100644 packages-node/publish-docs/test-node/test-helpers.js create mode 100644 packages/accordion/docs/features.md create mode 100644 packages/accordion/docs/overview.md create mode 100644 packages/ajax/docs/features.md create mode 100644 packages/ajax/docs/overview.md create mode 100644 packages/button/docs/features.md create mode 100644 packages/button/docs/overview.md create mode 100644 packages/calendar/docs/features.md create mode 100644 packages/calendar/docs/overview.md create mode 100644 packages/calendar/test-helpers/index.js create mode 100644 packages/checkbox-group/define.js create mode 100644 packages/checkbox-group/docs/features.md create mode 100644 packages/checkbox-group/docs/overview.md delete mode 100644 packages/collapsible/demo/custom-collapsible.js create mode 100644 packages/collapsible/docs/features.md create mode 100644 packages/collapsible/docs/overview.md create mode 100644 packages/combobox/docs/features.md delete mode 100644 packages/combobox/docs/google-combobox/assets/appleLogo.png delete mode 100644 packages/combobox/docs/google-combobox/assets/google-clear-icon.js delete mode 100644 packages/combobox/docs/google-combobox/assets/google-search-icon.js delete mode 100644 packages/combobox/docs/google-combobox/assets/google-voice-search-icon.js delete mode 100644 packages/combobox/docs/google-combobox/assets/googlelogo_color_272x92dp.png create mode 100644 packages/combobox/docs/overview.md delete mode 100644 packages/core/docs/guidelines/10-guidelines-definitions.md delete mode 100644 packages/core/docs/guidelines/20-guidelines-styling.md create mode 100644 packages/core/docs/guides/how-to/creating-a-custom-field.md create mode 100644 packages/core/docs/guides/how-to/get-started.md create mode 100644 packages/core/docs/guides/how-to/index.md create mode 100644 packages/core/docs/guides/index.md create mode 100644 packages/core/docs/guides/principles/definitions-and-terms.md create mode 100644 packages/core/docs/guides/principles/index.md create mode 100644 packages/core/docs/guides/principles/scoped-elements.md create mode 100644 packages/core/docs/guides/principles/styling.md create mode 100644 packages/core/docs/guides/principles/subclasser-apis.md create mode 100644 packages/core/docs/overview.md create mode 100644 packages/core/docs/rationales/side-effects.md create mode 100644 packages/core/test-helpers/index.js create mode 100644 packages/dialog/docs/features.md create mode 100644 packages/dialog/docs/overview.md delete mode 100644 packages/dialog/docs/slots-dialog-content.js create mode 100644 packages/fieldset/docs/features.md create mode 100644 packages/fieldset/docs/overview.md create mode 100644 packages/form-core/define.js delete mode 100644 packages/form-core/docs/choice-group/README.md create mode 100644 packages/form-core/docs/overview.md delete mode 100644 packages/form-core/docs/validate/README.md delete mode 100644 packages/form-core/docs/validate/assets/FlowDiagram.md delete mode 100644 packages/form-core/docs/validate/system.md create mode 100644 packages/form-core/test-helpers/index.js create mode 100644 packages/form-core/test-suites/index.js delete mode 100644 packages/form-integrations/docs/20-system-overview.md delete mode 100644 packages/form-integrations/docs/50-content-inside-fields.md delete mode 100644 packages/form-integrations/docs/60-dialog-integration.md create mode 100644 packages/form-integrations/docs/features.md create mode 100644 packages/form-integrations/docs/formatting-and-parsing.md create mode 100644 packages/form-integrations/docs/interaction-state.md create mode 100644 packages/form-integrations/docs/model-value.md create mode 100644 packages/form-integrations/docs/overview.md create mode 100644 packages/form-integrations/docs/styling.md create mode 100644 packages/form-integrations/docs/validate.md create mode 100644 packages/form/docs/features.md create mode 100644 packages/form/docs/overview.md create mode 100644 packages/helpers/define.js create mode 100644 packages/helpers/docs/action-logger.md create mode 100644 packages/helpers/docs/overview.md create mode 100644 packages/icon/docs/features.md create mode 100644 packages/icon/docs/overview.md create mode 100644 packages/input-amount/docs/features.md create mode 100644 packages/input-amount/docs/overview.md create mode 100644 packages/input-date/docs/features.md create mode 100644 packages/input-date/docs/overview.md create mode 100644 packages/input-datepicker/docs/features.md create mode 100644 packages/input-datepicker/docs/overview.md create mode 100644 packages/input-email/docs/features.md create mode 100644 packages/input-email/docs/overview.md create mode 100644 packages/input-iban/docs/features.md create mode 100644 packages/input-iban/docs/overview.md create mode 100644 packages/input-range/docs/features.md create mode 100644 packages/input-range/docs/overview.md create mode 100644 packages/input-stepper/docs/features.md create mode 100644 packages/input-stepper/docs/overview.md create mode 100644 packages/input/docs/features.md create mode 100644 packages/input/docs/overview.md create mode 100644 packages/listbox/define.js create mode 100644 packages/listbox/docs/features.md create mode 100644 packages/listbox/docs/overview.md create mode 100644 packages/listbox/test-suites/index.js delete mode 100644 packages/localize/_docs/amount-html.md delete mode 100644 packages/localize/_docs/date.md delete mode 100644 packages/localize/_docs/message.md delete mode 100644 packages/localize/_docs/number.md delete mode 100644 packages/localize/docs/10-features-overview.md delete mode 100644 packages/localize/docs/40-google-translate-integration.md create mode 100644 packages/localize/docs/dates.md create mode 100644 packages/localize/docs/features.md create mode 100644 packages/localize/docs/numbers.md create mode 100644 packages/localize/docs/overview.md create mode 100644 packages/localize/docs/rationale.md create mode 100644 packages/localize/docs/text.md delete mode 100644 packages/localize/test-helpers.js create mode 100644 packages/localize/test-helpers/index.js delete mode 100644 packages/overlays/docs/40-system-configuration.md create mode 100644 packages/overlays/docs/configuration.md create mode 100644 packages/overlays/docs/features.md create mode 100644 packages/overlays/docs/form-integration.md create mode 100644 packages/overlays/docs/overview.md create mode 100644 packages/overlays/docs/rationale.md create mode 100644 packages/overlays/docs/scope.md create mode 100644 packages/overlays/test-suites/index.js create mode 100644 packages/pagination/docs/features.md create mode 100644 packages/pagination/docs/overview.md delete mode 100644 packages/progress-indicator/demo/custom-progress-indicator.js create mode 100644 packages/progress-indicator/docs/overview.md create mode 100644 packages/radio-group/define.js create mode 100644 packages/radio-group/docs/features.md create mode 100644 packages/radio-group/docs/overview.md create mode 100644 packages/select-rich/define.js create mode 100644 packages/select-rich/docs/features.md create mode 100644 packages/select-rich/docs/overview.md create mode 100644 packages/select/docs/features.md create mode 100644 packages/select/docs/overview.md delete mode 100644 packages/singleton-manager/demo/fail/index.html delete mode 100644 packages/singleton-manager/demo/fail/server.js delete mode 100644 packages/singleton-manager/demo/singleton-complex/index.html delete mode 100644 packages/singleton-manager/demo/singleton-complex/server.js delete mode 100644 packages/singleton-manager/demo/singleton/index.html delete mode 100644 packages/singleton-manager/demo/singleton/server.js create mode 100644 packages/singleton-manager/docs/overview.md delete mode 100644 packages/singleton-manager/test/singleton-demo.test.js create mode 100644 packages/steps/define.js create mode 100644 packages/steps/docs/features.md create mode 100644 packages/steps/docs/overview.md create mode 100644 packages/switch/define.js create mode 100644 packages/switch/docs/features.md create mode 100644 packages/switch/docs/overview.md create mode 100644 packages/tabs/docs/features.md create mode 100644 packages/tabs/docs/overview.md create mode 100644 packages/textarea/docs/features.md create mode 100644 packages/textarea/docs/overview.md create mode 100644 packages/tooltip/docs/features.md create mode 100644 packages/tooltip/docs/overview.md create mode 100644 packages/validate-messages/README.md create mode 100644 packages/validate-messages/docs/features.md create mode 100644 packages/validate-messages/docs/overview.md create mode 100644 rocket.config.mjs diff --git a/.changeset/early-dolphins-build.md b/.changeset/early-dolphins-build.md new file mode 100644 index 000000000..9ec0dde9a --- /dev/null +++ b/.changeset/early-dolphins-build.md @@ -0,0 +1,5 @@ +--- +'babel-plugin-extend-docs': patch +--- + +Still replace tags if templates uses `.foo=${{ key: 'value' }}` diff --git a/.changeset/famous-bears-confess.md b/.changeset/famous-bears-confess.md new file mode 100644 index 000000000..f76dc859f --- /dev/null +++ b/.changeset/famous-bears-confess.md @@ -0,0 +1,23 @@ +--- +'remark-extend': minor +--- + +BREAKING CHANGE: Changing approach from overwriting extending files to using an import-based approach. + +Removed features: + +- `::replaceFrom` +- `::replaceBetween` +- `::addMdAfter` +- `::removeFrom` +- `::removeBetween` + +Added Features: + +- `::import` +- `::importBlock` +- `::importBlockContent` +- `::importSmallBlock` +- `::importSmallBlockContent` + +See the updated documentation for how to use this new approach. diff --git a/.changeset/odd-beds-clean.md b/.changeset/odd-beds-clean.md new file mode 100644 index 000000000..867fe5e5a --- /dev/null +++ b/.changeset/odd-beds-clean.md @@ -0,0 +1,5 @@ +--- +'providence-analytics': minor +--- + +BREAKING: Align exports fields. If you want to import from CLI instead of main entrypoint (`import { ... } from 'providence-analytics';`) using export maps, you can now do so with `import { ... } from 'providence-analytics/src/cli';` instead of `import { ... } from 'providence-analytics/src/cli/index.js';`. diff --git a/.changeset/silly-ants-melt.md b/.changeset/silly-ants-melt.md new file mode 100644 index 000000000..abd080871 --- /dev/null +++ b/.changeset/silly-ants-melt.md @@ -0,0 +1,40 @@ +--- +'@lion/accordion': minor +'@lion/button': minor +'@lion/calendar': minor +'@lion/checkbox-group': minor +'@lion/collapsible': minor +'@lion/combobox': minor +'@lion/core': minor +'@lion/dialog': minor +'@lion/fieldset': minor +'@lion/form': minor +'@lion/form-core': minor +'@lion/form-integrations': minor +'@lion/helpers': minor +'@lion/icon': minor +'@lion/input': minor +'@lion/input-amount': minor +'@lion/input-date': minor +'@lion/input-datepicker': minor +'@lion/input-email': minor +'@lion/input-iban': minor +'@lion/input-range': minor +'@lion/input-stepper': minor +'@lion/listbox': minor +'@lion/localize': minor +'@lion/overlays': minor +'@lion/pagination': minor +'@lion/progress-indicator': minor +'@lion/radio-group': minor +'@lion/select': minor +'@lion/select-rich': minor +'@lion/steps': minor +'@lion/switch': minor +'@lion/tabs': minor +'@lion/textarea': minor +'@lion/tooltip': minor +'@lion/validate-messages': minor +--- + +BREAKING: Align exports fields. This means no more wildcards, meaning you always import with bare import specifiers, extensionless. Import components where customElements.define side effect is executed by importing from '@lion/package/define'. For multi-component packages this defines all components (e.g. radio-group + radio). If you want to only import a single one, do '@lion/package/define-radio' for example for just lion-radio. diff --git a/.eleventyignore b/.eleventyignore new file mode 100644 index 000000000..3dc0e48c6 --- /dev/null +++ b/.eleventyignore @@ -0,0 +1,4 @@ +node_modules/** +/docs/_assets +/docs/_includes +/docs/_data diff --git a/.eslintignore b/.eslintignore index cdffae36b..9a1a5c81d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,5 @@ coverage/ bundlesize/ .history/ *.d.ts +_site-dev +_site diff --git a/.eslintrc.js b/.eslintrc.js index 7ffa5bd87..dc4b294f7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,8 @@ module.exports = { files: ['**/*.js'], rules: { 'wc/guard-super-call': 'off', // types will prevent you from calling the super if it's not in the base class, making the guard unnecessary + 'no-await-in-loop': 'off', + 'import/no-unresolved': 'off', // eslint not smart enough atm to understand package exports maps }, }, { diff --git a/.gitignore b/.gitignore index 7e8d30fea..09f5a7753 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,15 @@ local.log ## browserstack browserstack.err +## Rocket ignore files (need to be the full relative path to the folders) +docs/_merged_data/ +docs/_merged_assets/ +docs/_merged_includes/ + debug.log -!packages/singleton-manager/demo/**/node_modules +_site +_site-dev + +## generated test fiels +__output diff --git a/.markdownlint.json b/.markdownlint.json index beda11a36..da2c8aa29 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -2,6 +2,9 @@ "line-length": { "line_length": -1 }, + "fenced-code-language": false, + "no-inline-html": false, + "first-line-h1": false, "no-trailing-punctuation": { "punctuation": ".,;。,;:!" } diff --git a/.prettierignore b/.prettierignore index 85b847f95..63ecf735b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,5 @@ coverage/ CHANGELOG.md bundlesize/ +_site +_site-dev diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index 81b7fdd96..000000000 --- a/.storybook/main.js +++ /dev/null @@ -1,81 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -module.exports = { - stories: [ - '../{packages,packages-node}/*/README.md', - '../{packages,packages-node}/*/docs/*.md', - '../{packages,packages-node}/*/docs/!(assets)**/*.md', - '../packages/helpers/*/README.md', - '../docs/README.md', - '../docs/**/*.md', - '../README.md', - '../demo/README.md', - '../demo/docs/*.md', - ], - addons: [ - // order of tabs in addons panel - 'storybook-prebuilt/addon-actions/register.js', - 'storybook-prebuilt/addon-knobs/register.js', - 'storybook-prebuilt/addon-a11y/register.js', - 'storybook-prebuilt/addon-docs/register.js', - // no tab in addons panel (e.g. load order does not matter here) - 'storybook-prebuilt/addon-backgrounds/register.js', - 'storybook-prebuilt/addon-links/register.js', - 'storybook-prebuilt/addon-viewport/register.js', - ], - addons: [ - 'storybook-prebuilt/addon-docs/register.js', - 'storybook-prebuilt/addon-actions/register.js', - 'storybook-prebuilt/addon-knobs/register.js', - 'storybook-prebuilt/addon-a11y/register.js', - 'storybook-prebuilt/addon-backgrounds/register.js', - 'storybook-prebuilt/addon-links/register.js', - 'storybook-prebuilt/addon-viewport/register.js', - ], - esDevServer: { - nodeResolve: true, - watch: true, - open: true, - }, - rollup: config => { - // temporarily hard copy all needed global files as all tested rollup plugins flatten the - // directory structure - // `rollup-plugin-copy` might work if issue 37 is resolved - // https://github.com/vladshcherbin/rollup-plugin-copy/issues/37 - config.plugins.push({ - generateBundle() { - this.emitFile({ - type: 'asset', - fileName: 'packages/form-integrations/dev-assets/FormatMixinDiagram-1.svg', - source: fs.readFileSync( - path.join( - __dirname, - '../packages/form-integrations/dev-assets/FormatMixinDiagram-1.svg', - ), - ), - }); - this.emitFile({ - type: 'asset', - fileName: 'packages/form-integrations/dev-assets/FormatMixinDiagram-2.svg', - source: fs.readFileSync( - path.join( - __dirname, - '../packages/form-integrations/dev-assets/FormatMixinDiagram-2.svg', - ), - ), - }); - this.emitFile({ - type: 'asset', - fileName: 'packages/form-integrations/dev-assets/FormatMixinDiagram-3.svg', - source: fs.readFileSync( - path.join( - __dirname, - '../packages/form-integrations/dev-assets/FormatMixinDiagram-3.svg', - ), - ), - }); - }, - }); - }, -}; diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index dcd7618be..000000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,27 +0,0 @@ - diff --git a/.storybook/preview.js b/.storybook/preview.js deleted file mode 100755 index aa4ddac3a..000000000 --- a/.storybook/preview.js +++ /dev/null @@ -1,49 +0,0 @@ -import { - addDecorator, - addParameters, - setCustomElements, - withA11y, -} from '@open-wc/demoing-storybook'; -import { sortEachDepth } from '../packages/helpers/index.js'; - -async function run() { - // const customElements = await ( - // await fetch(new URL('../custom-elements.json', import.meta.url)) - // ).json(); - setCustomElements({}); - - addDecorator(withA11y); - - addParameters({ - a11y: { - config: {}, - options: { - checks: { 'color-contrast': { options: { noScroll: true } } }, - restoreScroll: true, - }, - }, - docs: { - iframeHeight: '200px', - }, - options: { - showRoots: true, - storySort: sortEachDepth([ - [ - 'Intro', - 'Forms', - 'Buttons', - 'Overlays', - 'Navigation', - 'Localize', - 'Icons', - 'Others', - '...', - ], - ['Intro', 'Features Overview', '...', 'Validation', 'System'], - ['Overview', '...', '_internals'], - ]), - }, - }); -} - -run(); diff --git a/README.md b/README.md index 7c110f021..77c2b9e4f 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,60 @@ -# Lion Web Components +

+ Lion +

-```js script -export default { - title: 'Intro/Lion Web Components', -}; -``` +

+ GitHub Actions workflow status + GitHub Actions workflow status + Todos +

-Lion web components is a set of highly performant, accessible and flexible Web Components. -They provide an unopinionated, white label layer that can be extended to your own layer of components. +

+ Website + · + Guides + · + Components + · + Documentation + · + Blog +

-For some more details see the [announcement blog post](https://medium.com/ing-blog/ing-open-sources-lion-a-library-for-performant-accessible-flexible-web-components-22ad165b1d3d). +

-[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.comgithub.com/ing-bank/lion)](https://www.tickgit.com/browse?repo=github.com/ing-bank/lion) +**Lion is a set of highly performant, accessible and flexible Web Components.!** -## Demos +They provide an unopinionated, white-label layer that can be extended to your own layer of components. -We do have a [live Storybook](http://lion-web-components.netlify.com) which shows all our components. +- **High Performance:** Focused on great performance in all relevant browsers with a minimal number of dependencies. +- **Accessibility:** Aimed at compliance with the WCAG 2.1 AA standard to create components that are accessible for everybody. +- **Flexibility:** Provides solutions through Web Components and JavaScript classes which can be used, adopted and extended to fit all needs. +- **Modern Code:** Lion is distributes as pure es modules. +- **Exposes functions/classes and Web Components:** Ships a functionality in it's most appropriate form. -**Please note:** This project uses Yarn [Workspaces](https://classic.yarnpkg.com/en/docs/workspaces). If you want to run all demos locally you need to get [Yarn](https://classic.yarnpkg.com/en/docs/install) and install all dependencies by executing `yarn install`. - -The code examples make use of [Javascript tagged template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) which are a key component of the [lit-html engine](https://lit-html.polymer-project.org/) used in Lion. -Additionally imports like `import '@lion/form/lion-form.js'` need to be transformed somehow, for example by [es-dev-server](https://open-wc.org/developing/es-dev-server.html#node-resolve). - -## Features - -- High Performance - Focused on great performance in all relevant browsers with a minimal number of dependencies -- Accessibility - Aimed at compliance with the WCAG 2.1 AA standard to create components that are accessible for everybody -- Flexibility - Provides solutions through Web Components and JavaScript classes which can be used, adopted and extended to fit all needs -- Pure ES Modules -- Exposes functions/classes and Web Components - -> Note: These demos may look a little bland but that is on purpose. They only come with functional stylings. +> Note: Our demos may look a little bland but that is on purpose. They only come with functional stylings. > This makes sense as the main use case is to extend those components and if you do you do not want to override existing stylings. +

+ Explore the Lion Guides  ▶ +

+ ## How to install ```bash @@ -82,7 +104,7 @@ You can also use the lion elements directly, although this is likely not a commo ```html @@ -150,18 +172,17 @@ The accessibility column indicates whether the functionality is accessible in it ## Technologies -Lion Web Components aims to be future proof and use well-supported proven technology. The stack we have chosen should reflect this. +Lion Web Components aims to be future-proof and use well-supported proven technology. The stack we have chosen should reflect this. - [lit-html](https://lit-html.polymer-project.org) and [lit-element](https://lit-element.polymer-project.org) - [npm](http://npmjs.com) - [yarn](https://yarnpkg.com) -- [open-wc](https://open-wc.org) -- [Karma](https://karma-runner.github.io) +- [Open Web Components](https://open-wc.org) +- [Modern Web](https://modern-web.dev) - [Mocha](https://mochajs.org) - [Chai](https://www.chaijs.com) - [ESLint](https://eslint.org) - [prettier](https://prettier.io) -- [Storybook](https://storybook.js.org) - [ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) - Lots and lots of tests @@ -180,6 +201,8 @@ Check out our [coding guidelines](https://lion-web-components.netlify.app/?path= ## How to contribute +**Please note:** This project uses Yarn [Workspaces](https://classic.yarnpkg.com/en/docs/workspaces). If you want to run all demos locally you need to get [Yarn](https://classic.yarnpkg.com/en/docs/install) and install all dependencies by executing `yarn install`. + Lion Web Components are only as good as its contributions. Read our [contribution guide](https://github.com/ing-bank/lion/blob/master/CONTRIBUTING.md) and feel free to enhance/improve Lion. We keep feature requests closed while we're not working on them. diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b4528d72df18b9d3cc2f8ecb488e816586857ef8 GIT binary patch literal 19142 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 literal 0 HcmV?d00001 diff --git a/demo/docs/20-lea-tabs.md b/demo/docs/20-lea-tabs.md deleted file mode 100644 index 5c3154b10..000000000 --- a/demo/docs/20-lea-tabs.md +++ /dev/null @@ -1,231 +0,0 @@ -# lea Tabs - -> This is not a real implementation! -> -> It is an example of how you can reuse the functionality of Lion to create your own Style System - -`lea-tabs` implements tabs view to allow users to quickly move between a small number of equally important views. - -```js script -import { html } from '@lion/core'; -import { LitElement } from '@lion/core'; - -import '../lea-tabs.js'; -import '../lea-tab.js'; -import '../lea-tab-panel.js'; - -export default { - title: 'Intro/Tabs Example', -}; -``` - -```js preview-story -export const main = () => html` - - Info - Info page with lots of information about us. - Work - Work page that showcases our work. - -`; -``` - -## How to use - -### Installation - -```sh -npm i --save @lion/tabs; -``` - -### Usage - -```js -import '@lion/tabs/lea-tabs.js'; -``` - -```html - - Info - Info page with lots of information about us. - Work - Work page that showcases our work. - -``` - -## Examples - -### Selected Index - -You can set the `selectedIndex` to select a certain tab. - -```js preview-story -export const selectedIndex = () => html` - - Info - Info page with lots of information about us. - Work - Work page that showcases our work. - -`; -``` - -### Slots Order - -The tab and panel slots are ordered by DOM order. - -This means you can switch the grouping in your `lea-tabs` from tab + panel to all tabs first or all panels first. - -```js preview-story -export const slotsOrder = () => html` - - Info - Work - Info page with lots of information about us. - Work page that showcases our work. - -`; -``` - -### Distribute New Elements - -Below, we demonstrate on how you could dynamically add new tab + panels. - -```js preview-story -export const distributeNewElements = () => { - const tagName = 'lea-tabs-experimental'; - if (!customElements.get(tagName)) { - customElements.define( - tagName, - class extends LitElement { - static get properties() { - return { - __collection: { type: Array }, - }; - } - render() { - return html` -

    Append

    - - - tab 1 - panel 1 - tab 2 - panel 2 - -
    -

    Push

    - - - tab 1 - panel 1 - tab 2 - panel 2 - ${this.__collection.map( - item => html` - ${item.button} - ${item.panel} - `, - )} - - `; - } - constructor() { - super(); - this.__collection = []; - } - __handleAppendClick() { - const tabsElement = this.shadowRoot.querySelector('#appendTabs'); - const c = 2; - const n = Math.floor(tabsElement.children.length / 2); - for (let i = n + 1; i < n + c; i += 1) { - const tab = document.createElement('lea-tab'); - tab.setAttribute('slot', 'tab'); - tab.innerText = `tab ${i}`; - const panel = document.createElement('lea-tab-panel'); - panel.setAttribute('slot', 'panel'); - panel.innerText = `panel ${i}`; - tabsElement.append(tab); - tabsElement.append(panel); - } - } - __handlePushClick() { - const tabsElement = this.shadowRoot.querySelector('#pushTabs'); - const i = Math.floor(tabsElement.children.length / 2) + 1; - this.__collection = [ - ...this.__collection, - { - button: `tab ${i}`, - panel: `panel ${i}`, - }, - ]; - } - }, - ); - } - return html` `; -}; -``` - -One way is by creating the DOM elements and appending them as needed. - -Inside your `lea-tabs` extension, an example for appending nodes on a certain button click: - -```js -__handleAppendClick() { - const tabsAmount = this.children.length / 2; - const tab = document.createElement('lea-tab'); - tab.setAttribute('slot', 'tab'); - tab.innerText = `tab ${tabsAmount + 1}`; - const panel = document.createElement('lea-tab-panel'); - panel.setAttribute('slot', 'panel'); - panel.innerText = `panel ${tabsAmount + 1}`; - this.append(tab); - this.append(panel); -} -``` - -The other way is by adding data to a Lit property where you loop over this property in your template. -You then need to ensure this causes a re-render. - -```js -__handlePushClick() { - const tabsAmount = this.children.length; - myCollection = [ - ...myCollection, - { - button: `tab ${tabsAmount + 1}`, - panel: `panel ${tabsAmount + 1}`, - }, - ]; - renderMyCollection(); -} -``` - -Make sure your template re-renders when myCollection is updated. - -```html - - ${myCollection.map(item => html` - ${item.button} - ${item.panel} - `)} - -``` - -## Rationale - -### No separate active/focus state when using keyboard - -We will immediately switch content as all our content comes from light dom (e.g. no latency) - -See Note at - -> It is recommended that tabs activate automatically when they receive focus as long as their -> associated tab panels are displayed without noticeable latency. This typically requires tab -> panel content to be preloaded. - -### Panels are not focusable - -Focusable elements should have a means to interact with them. Tab panels themselves do not offer any interactiveness. -If there is a button or a form inside the tab panel then these elements get focused directly. diff --git a/demo/lea-tab-panel.js b/demo/lea-tab-panel.js deleted file mode 100644 index c9b048d53..000000000 --- a/demo/lea-tab-panel.js +++ /dev/null @@ -1,3 +0,0 @@ -import { LeaTabPanel } from './src/LeaTabPanel.js'; - -customElements.define('lea-tab-panel', LeaTabPanel); diff --git a/demo/lea-tab.js b/demo/lea-tab.js deleted file mode 100644 index 5fb7621ab..000000000 --- a/demo/lea-tab.js +++ /dev/null @@ -1,3 +0,0 @@ -import { LeaTab } from './src/LeaTab.js'; - -customElements.define('lea-tab', LeaTab); diff --git a/demo/lea-tabs.js b/demo/lea-tabs.js deleted file mode 100644 index 29092c758..000000000 --- a/demo/lea-tabs.js +++ /dev/null @@ -1,3 +0,0 @@ -import { LeaTabs } from './src/LeaTabs.js'; - -customElements.define('lea-tabs', LeaTabs); diff --git a/docs/404.md b/docs/404.md new file mode 100644 index 000000000..9bdb1a891 --- /dev/null +++ b/docs/404.md @@ -0,0 +1,4 @@ +--- +permalink: 404.html +layout: layout-404 +--- diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 74610c7a8..000000000 --- a/docs/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Coding Guidelines - -```js script -export default { - title: 'Guidelines/Intro', -}; -``` - -First be sure to understand our [definitions](?path=/docs/guidelines-definitions--page). - -- [Guidelines for Styling](?path=/docs/guidelines-styling--page) -- [Guidelines for Scoped Elements](?path=/docs/guidelines-scoped-elements--page) -- [Guidelines for SubClasser APIs](?path=/docs/guidelines-subclasser-apis--page) diff --git a/docs/_assets/_static/icons/android-chrome-192x192.png b/docs/_assets/_static/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..3de4ce3672efd9c535ec399f99b719e7ef163741 GIT binary patch literal 9925 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 literal 0 HcmV?d00001 diff --git a/docs/_assets/_static/icons/android-chrome-512x512.png b/docs/_assets/_static/icons/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..2f4b2547dfbc6b3782e215ba593565967977351a GIT binary patch literal 32835 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 H+9>Eh=)SAQ literal 0 HcmV?d00001 diff --git a/docs/_assets/_static/icons/favicon-16x16.png b/docs/_assets/_static/icons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..da06d9604d0afe72435f83bc9b5583340f915701 GIT binary patch literal 837 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>nP1YRy@y z4Gav~fzm*|=|Qr&o^0z z)@-%L4Ass&jjAN2+EnGrM5V5Ljr=J2ya@UFbd{zo)w&dw@&v`~5Sjc)prCA4sBBu0 z4A9d5|NnciE$apP*`OrIFPOppdO+JNgWNA-LElt8zBxzzHg9fjt$aMg#}971(LI8 z6n$3U{4i@~bi}8R$}B8v*6`-!u(m#6I#l+J@0nPi(jtd#Gj_D7G*6klxqJ2OwYyC` z!ra3A;tn3ZeERnB>;8e98VlAeTJ?;b`IQvUtf*U7yQ&Hn_%FFXfssL3TF_|;dzm@V z5vnDw5hW>!C8<`)MX5lF!3gLUT>~Rs1CtO#Q!7IQD^n9~14AnVgMU38pHVdA=BH$) zRpQprf6>4ns6i5BLvVgtNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E;Z-3KB|(Yh z3I#>^X_+~x3MG{VsS23|CCLm76>}bc;^8O^)6h8OfBKB)(;xZee9%@5v&} z!U`@8CWlj)l{bedoW618#E~;cWR9?(Ztz&(rN{6}T(IPmlj&5T6%3xPelF{r5}E+a C0T4$3 literal 0 HcmV?d00001 diff --git a/docs/_assets/_static/icons/favicon-32x32.png b/docs/_assets/_static/icons/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..31c2edecd044ba4ec5451d8f2cd0c2a9af9a32fa GIT binary patch literal 1375 zcmZ`%c~FyA5Pt+M7(}f&QobbQz99{#PSh5hFak;>A)F%S`f`wjB;$r;H2oM;UBQ#s#nRHw=^0H|aE;PL?Q3PP@j z0F(&Hr|z+BG6w4FGOQ<_38Rbf`12sx>rJil`*W9yNOm^AM#nVgMXDqut;}zF zEAX62v=xw1DN!#C{|9WViW=G#XUrk}>t>V^TrSY<7HFmLWd!0bJ>6^JG}zeis?L6! zPAwr?a>*rmWK#~QSWfaYl@ipl2(^@iW+9Lc3~VUnLhfyqd{jn+|7mvc+nrIx*(CdB z$}TIX%^BrX(LBX0NUBOrZ>`|lHj&{YTeS?xv_eV4HdCwx19Kb7 zfGyajWw>J7@9_;Y>?3Zx+CJv3XAM(rz|C8XUy=BDCKB4x)5OX0l~ZcP zdxfqhZ|D5uxUa8p63eUcD|>o-RzBw5^?7~2{Cct1wIWf#`=Dm=8Qk1>-@yH40m)r> zkL+IWjT>>XwKndOiOFjdUrfEvS@v0X(vg8r8AszskE~8F#0}vldVG_EFQx~c>_)gp z@O{SLr(2Lo%h0N zHg<~4#pv^A5pk<@w>U!zPUg|yhN3#w^u}+!_Wc!S^wV1h$EK0}1$RUvN$o$n+iP2v zN6%b;nBTnbEY@>AKwjG|mCIXCcn^2JJo$1e{8&e3e!<>zCrKP_K-`@hlOjAW=cuIM z?BK|npveT!;o%dfPdVzx=IxOv47z;@Hwz=Wei$CG1`W>6J}Vd%On!HH1)ebbR2Lk) z5Wi?aXh`FQMYH{1b_arh+-;#tRh<`Mp_y1p9;Q)Zs7PIkLIq-lu`$uY*l1zAJSIUD zBNQbh@P#oVp)l|Dj&=VDFk3VRt@Hl_xc#eM!+;2XhAfK~b0|wu;BYtuh7zM)t+b*7 zOR4U_%xVNW=*j2^bWWm#YtMeK^dqzR;-l2fK`e|2U2>Ns&cXv&p(FkJwq!{5c8tW9WxDL`6^ KM0{+m!u>aV`T5`g literal 0 HcmV?d00001 diff --git a/docs/_assets/_static/icons/mstile-150x150.png b/docs/_assets/_static/icons/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..58eec7e9ac82f722cc693ebf3631f63f68802b8c GIT binary patch literal 5770 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 + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/docs/_assets/logo.svg b/docs/_assets/logo.svg new file mode 100644 index 000000000..dec159884 --- /dev/null +++ b/docs/_assets/logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_assets/style.css b/docs/_assets/style.css new file mode 100644 index 000000000..04e56e465 --- /dev/null +++ b/docs/_assets/style.css @@ -0,0 +1,23 @@ +body[layout='layout-home'] .markdown-body .call-to-action:nth-of-type(2) { + --primary-color: #222; + --primary-color-lighter: #333; + --primary-color-darker: #000; +} + +.markdown-body img { + width: 100%; +} + +mdjs-preview { + margin-bottom: 20px; +} + +#main-header a[href="/blog/"] { + display: none; +} + +@media screen and (min-width: 1024px) { + #main-header a[href="/blog/"] { + display: block; + } +} diff --git a/docs/_assets/variables.css b/docs/_assets/variables.css new file mode 100644 index 000000000..181a4b183 --- /dev/null +++ b/docs/_assets/variables.css @@ -0,0 +1,41 @@ +html { + --primary-color: #a07f23; + --primary-color-lighter: #d1a62f; + --primary-color-darker: #705918; + --primary-color-accent: #cee5f6; + --primary-text-color: #2c3e50; + --primary-lines-color: #ccc; + + /* Contrast colors */ + --contrast-color-light: #fff; + --contrast-color-dark: #1d3557; + + /* background-colors */ + --page-background: white; + --footer-background: rgba(0, 0, 0, 0.1); + + --text-color: black; +} + +html.dark { + --primary-color: #e63946; + --primary-color-lighter: #e25761; + --primary-color-darker: #a22831; + --primary-color-accent: #cee5f6; + --primary-text-color: #eee; + + /* Contrast colors */ + --contrast-color-light: #fff; + --contrast-color-dark: #1d3557; + + /* background-colors */ + --page-background: #333; + --footer-background: #4f4f4f; + + --text-color: white; + + --markdown-octicon-link: white; + --markdown-syntax-background-color: #a0a0a0; + --markdown-link-color: #fb7881; + --markdown-blockquote-color: #c9e3ff; +} diff --git a/docs/_data/footer.json b/docs/_data/footer.json new file mode 100644 index 000000000..c5053c70b --- /dev/null +++ b/docs/_data/footer.json @@ -0,0 +1,41 @@ +[ + { + "name": "Discover", + "children": [ + { + "text": "Blog", + "href": "/blog/" + }, + { + "text": "Help and Feedback", + "href": "https://github.com/ing-bank/lion/issues" + } + ] + }, + { + "name": "Follow", + "children": [ + { + "text": "Github", + "href": "https://github.com/ing-bank/lion" + }, + { + "text": "Twitter", + "href": "https://twitter.com/daKmoR" + }, + { + "text": "Slack", + "href": "/about/slack/" + } + ] + }, + { + "name": "Support", + "children": [ + { + "text": "Contribute", + "href": "https://github.com/ing-bank/lion/blob/master/CONTRIBUTING.md" + } + ] + } +] diff --git a/docs/_data/site.cjs b/docs/_data/site.cjs new file mode 100644 index 000000000..7cf118bc8 --- /dev/null +++ b/docs/_data/site.cjs @@ -0,0 +1,22 @@ +module.exports = async function () { + return { + dir: 'ltr', + lang: 'en', + name: 'Lion', + description: 'Fundamental white label web components for building your design system', + socialLinks: [ + { + name: 'GitHub', + url: 'https://github.com/ing-bank/lion', + }, + ], + gitSiteUrl: 'https://github.com/ing-bank/lion', + gitBranch: 'master', + helpUrl: 'https://github.com/ing-bank/lion/issues', + logoAlt: 'Lion Logo', + iconColorMaskIcon: '#3f93ce', + iconColorMsapplicationTileColor: '#1d3557', + iconColorThemeColor: '#1d3557', + analytics: 'G-151V7YV71K', + }; +}; diff --git a/docs/about/slack.md b/docs/about/slack.md new file mode 100644 index 000000000..90b4a8b8d --- /dev/null +++ b/docs/about/slack.md @@ -0,0 +1,5 @@ +# Slack + +You can also find us on the Polymer Slack in the [#lion](https://polymer.slack.com/archives/CJGFWJN9J) channel. + +You can join the Polymer Slack by visiting [https://www.polymer-project.org/slack-invite](https://www.polymer-project.org/slack-invite). diff --git a/docs/blog/controlling-exports.md b/docs/blog/controlling-exports.md new file mode 100644 index 000000000..1500627fc --- /dev/null +++ b/docs/blog/controlling-exports.md @@ -0,0 +1,173 @@ +--- +title: Controlling exports +published: true +description: Maintainer can now define their public api of a package itself. +date: 2021-03-09 +tags: [javascript, exports] +cover_image: /blog/images/controlling-exports-cover-image.jpg +--- + +When publishing npm packages it can often be hard to understand what users are actually using. + +Basically, JavaScript allows you to write imports like this + +```js +import { addLeadingZero } '@lion/localize/src/date/utils/addLeadingZero.js'; +``` + +We as the maintainers of that package however consider this internal code, so any changes to it will not result in a new breaking change update. +So if you depend on this directly then your code may break with any minor or patch update. + +So why would we even "allow" such imports? Because so far there was no way to actually define and enforce what a maintainer considers to be the public API of the package. Now, with the introduction of node's [Package Entry Points](https://nodejs.org/api/packages.html#packages_package_entry_points) and the adoption of it in [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve#package-entrypoints) it can now be used in node, [@web/dev-server](https://modern-web.dev/docs/dev-server/overview/) and [rollup](https://rollupjs.org/). + +How can you use those `Package Entry Points`? + +Let's assume you have these two files in your `src` directory. + +```js +// src/index.js +export { foo } from './public.js'; + +// src/public.js +export const foo = 'public foo'; + +// src/internal.js +export const bar = 'internal bar'; +``` + +If you publish the package "normally" then users will be able to write imports like this + +```js +import { foo } from 'my-pkg'; +import { foo } from 'my-pkg/src/public.js'; +import { bar } from 'my-pkg/src/internal.js'; +``` + +This has multiple issues, described in use cases: + +1. Case 1: For maintenance purposes, we want to split `public.js` in `featureA.js` and `helpers.js`. Now all imports that use `import { foo } from 'my-pkg/src/public.js';` will break. +2. Case 2: We found a package that solved what we did in `internal.js` in a more generic way. We don't treat it as public API, so we actually go ahead and get rid of this file. Now all imports for `import { bar } from 'my-pkg/src/internal.js';` will break. + +Instead, what we actually want is all our consumers using the intended public API, which is + +```js +import { foo } from 'my-pkg'; +``` + +This way, above cases 1 and 2 just don't have any effect and we can freely refactor our codebase without introducing breaking changes. This means we can keep improving our code without disturbing our users. It's a win-win situation 🎉 + +Now, if someone tries to use a not defined export, like + +```js +import { bar } from 'my-pkg/src/internal.js'; +``` + +Then an error will be thrown + +``` +Could not resolve import "my-pkg/src/internal.js" +``` + +If a users needs access to `bar` then a GitHub Issue/Discussion should be opened to request it. +Maintainers can then have a discussion if they want to make this part of the public API or not. + +## Using consumer import in your own code + +An additional benefit of using Package Entry Points is that you can write imports in the same way as your consumers. + +So instead of writing demos or tests like + +```js +import { LionInput } from '../src/LionInput.js'; +``` + +we can now write + +```js +import { LionInput } from '@lion/input'; +``` + +This has the following benefits: + +- We can make sure everything we are demoing/testing is actually part of the public API +- Users can read / copy our demo code and it just works +- We can move files around without needing to adjust our demos/docs/tests + +## Exports for a single web component + +Usage: + +```js +// only the classes +import { MyElement } from 'my-element'; + +// OR + +// execute customElements.define +import 'my-element/define'; +``` + +Package Entry Points: + +```json +"exports": { + ".": "./src/index.js", + "define": "./src/my-element.js", +} +``` + +## Exports for multiple web components + +Usage: + +```js +// only the classes +import { MyElement, SubElement } from 'my-element'; + +// OR + +// execute customElements.define for all elements +import 'my-element/define'; + +// execute customElements.define for a single element +import 'my-element/define-my-element'; +import 'my-element/define-sub-element'; +``` + +Package Entry Points: + +```json +"exports": { + ".": "./src/index.js", + "define": "./src/define.js", + "define-my-element": "./src/my-element.js", + "define-sub-element": "./src/sub-element.js", +} +``` + +in this case, the `src/define.js` should not contain any `customElements.define`, but instead it just imports the other define files + +```js +import 'my-element/define-my-element'; +import 'my-element/define-sub-element'; +``` + +## What does it mean for Lion? + +Imports that worked before will need be be adjusted as they will no longer work. +This is a breaking change. + +```js +// no longer works +import '@lion/input/lion-input'; +import '@lion/input/lion-input.js'; +import { LionInput } from '@lion/input/src/LionInput.js'; + +// works +import '@lion/input/define'; +import { LionInput } from '@lion/input'; +``` + +--- + +Photo by Curology on Unsplash diff --git a/docs/extending-documentation.md b/docs/blog/extending-documentation.md similarity index 88% rename from docs/extending-documentation.md rename to docs/blog/extending-documentation.md index 29f4b4e00..e8caad715 100644 --- a/docs/extending-documentation.md +++ b/docs/blog/extending-documentation.md @@ -1,12 +1,13 @@ -# Extending Lion Documentation +--- +title: Extending Lion Documentation +published: true +description: Extending a component library and its documentation for a speedy design system +date: 2020-12-01 +tags: javascript, documentation, demos +cover_image: https://miro.medium.com/max/2000/1*NZ6tdtJHHJjxtPmIFxWpGw.jpeg +--- -```js script -export default { - title: 'Guidelines/Extending documentation', -}; -``` - -If you extend [Lion](https://lion-web-components.netlify.app/) components, you don't only want to reuse the components, but you probably want to reuse the documentation (Storybook demos) as well. Wouldn't it be nice to just take it all from lion, but replace it with your own design system extension, so you don't have the extra maintenance of essentially copying the docs from `Lion` for your own design system implementation? +If you extend [Lion](https://lion-web.netlify.app/) components, you don't only want to reuse the components, but you probably want to reuse the documentation (Storybook demos) as well. Wouldn't it be nice to just take it all from lion, but replace it with your own design system extension, so you don't have the extra maintenance of essentially copying the docs from `Lion` for your own design system implementation? In this blog we will explain how `Lion` supports this use case, and allows you to extend not just the components, but also the documentation. @@ -29,13 +30,13 @@ For step 1, we can use `@open-wc/demoing-storybook` version 2 or higher, which u Install it manually (and see the docs for configuring): -```sh +```bash npm i @open-wc/demoing-storybook --save-dev ``` Or scaffold it with basic configuration by doing -```sh +```bash npm init @open-wc ``` @@ -66,11 +67,11 @@ This step alone should already give you the `LionTabs` docs inside your own Stor Potentially the hardest part is to analyse your extension `LeaTabs`, and to figure out how we should transform the import paths for `LionTabs` to new paths to your `LeaTabs`. -To do this we make use of [Providence](https://lion-web-components.netlify.app/?path=/docs/tools-providence-main--run-providence). This tool has a command that creates a full map of all the import paths of a reference project (`Lion`) and can replace them with the correct paths of a target project (`Lea`). +To do this we make use of [Providence](https://lion-web.netlify.app/?path=/docs/tools-providence-main--run-providence). This tool has a command that creates a full map of all the import paths of a reference project (`Lion`) and can replace them with the correct paths of a target project (`Lea`). So lets install it: -```sh +```bash npm i providence-analytics --save-dev ``` @@ -86,7 +87,7 @@ The `--prefix-from` and `--prefix-to` are the prefixes of the project you extend If you know you only use a single component from lion, you can reduce the time the tool needs for analysis, by specifying this package `-r 'node_modules/@lion/tabs'`. -Running the script will create a `providence-extend-docs-data.json` file, with all from/to information. You can change the name / location of the output file, refer to [Providence Documentation](https://lion-web-components.netlify.app/?path=/docs/tools-providence-main--run-providence) for this. +Running the script will create a `providence-extend-docs-data.json` file, with all from/to information. You can change the name / location of the output file, refer to [Providence Documentation](https://lion-web.netlify.app/?path=/docs/tools-providence-main--run-providence) for this. #### Running it automatically when upgrading lion dependency @@ -103,13 +104,13 @@ Inside ING, our design system also makes use of this providence tool to create t Now that we have a JSON file with all the information we need to know about to replace import paths and tagnames inside templates, we can start transforming the `LionTabs` documentation to `LeaTabs` documentation. -For this, we created a `babel-plugin` called [babel-plugin-extend-docs](https://lion-web-components.netlify.app/?path=/docs/tools-babelpluginextenddocs--page). +For this, we created a `babel-plugin` called [babel-plugin-extend-docs](https://lion-web.netlify.app/?path=/docs/tools-babelpluginextenddocs--page). This will analyse the JavaScript script and story content inside the markdown files, which uses [MDJS](https://open-wc.org/mdjs/) syntax, and transform it on the fly in `es-dev-server`, as well as on rollup build for production. So all you need to do is to install this plugin: -```sh +```bash npm i babel-plugin-extend-docs --save-dev ``` @@ -164,7 +165,7 @@ In some cases you don't want to show all examples of how to use a component. Som In our example, we will show you have to remove the `Rationale` section that you would normally inherit from the `Lion` documentation. -For this step we make use of a remark plugin for the MD content, similar to how you would use a babel plugin for JS content. It is called [Remark extend](https://lion-web-components.netlify.app/?path=/docs/tools-remark-extend--page). +For this step we make use of a remark plugin for the MD content, similar to how you would use a babel plugin for JS content. It is called [Remark extend](https://lion-web.netlify.app/?path=/docs/tools-remark-extend--page). It will let you add, remove or replace sections or specific words. First of all we need to add the plugin to the `.storybook/main.js`: @@ -256,7 +257,7 @@ Or you can add an extra paragraph below the content. Create a fenced codeblock: ::removeMdAfter(':scope:last-child') ``` -> See [Remark extend](https://lion-web-components.netlify.app/?path=/docs/tools-remark-extend--page) for more information +> See [Remark extend](https://lion-web.netlify.app/?path=/docs/tools-remark-extend--page) for more information ### Lea Tabs Special Feature diff --git a/docs/blog/extending-lions-website.md b/docs/blog/extending-lions-website.md new file mode 100644 index 000000000..00a770745 --- /dev/null +++ b/docs/blog/extending-lions-website.md @@ -0,0 +1,124 @@ +--- +title: Extending lions website +published: false +description: A static website with docs and demos for lion +date: 2021-03-10 +tags: [javascript, rocket, documentation] +cover_image: /blog/images/introducing-lions-website-cover-image.jpg +--- + +After a month of preparations we can finally present to you our new website. With it we are enabled to give more context to each of our components. +Right now it's more or less a port for our existing demos from storybook. But we can organize it in a nicer way by splitting it into components, docs, guides and blog sections. + +## Importing Content into Markdown files + +We now use a system to import content from one markdown file into another. +So let's say you find the documentation of `input-amount` useful and you want to present it on your page as well. +Anywhere in your documentation you can now write. + +👉 `docs/input-amount.md` + +````md +# Input Amount + +```js ::import('@lion/input-amount/docs/overview.md', 'heading[depth=1] ~ *') + +``` +```` + +So when you now go to `https://domain.com/input-amount/` you will actually see the content from `@lion/input-amount/docs/overview.md`. + +Why is it a `js code block`? + +- You can define a start and end for what should be imported (using [unist-util-select](https://github.com/syntax-tree/unist-util-select#support)) +- You can add adjustments to the content as a function +- As links like `[go there](@lion/input-amount/docs/overview.md)` would not work anyways, having one syntax that allows for additional features is enough + +### Importing Partial Content + +Quite often you probably don't want to get the full file, so there is a special helper for that. + +Let's assume you have the following source file + +```md +# First Headline + +Content of first headline + +## Second Headline + +Content of second headline + +## Third Headline + +Content of Third headline +``` + +and you only want to get the 2nd "block" e.g. 2nd headline + text. + +With `importBlock` you can get exactly that. + +A block starts with a headline and ends when the next headline of an equal level starts. + +Note: importBlock is a faster way of writing imports for headlines + +```md +::importBlock('./path/to/file.md', '## red') +// is the same as +::import('./path/to/file.md', 'heading[depth=2]:has([value=red])', 'heading[depth=2]:has([value=red]) ~heading[depth=2]') +``` + +If you want to know more please look at the documentation for [remark-extend](../docs/node-tools/remark-extend/overview.md). + +## Upgrading Documentation + +Unfortunately this is quite a different concept then what we used with storybook before. Luckily the content is very much the same. + +Let's convert an example page + +### FROM + +````md +# Calendar + +`lion-calendar` is a reusable and accessible calendar view. It depends on [calendar](?path=/docs/calendar--default-story). + +```js script +import { html, css } from '@lion/core'; +import './lion-calendar.js'; + +export default { + title: 'Others/Calendar', +}; +``` + +... +```` + +### TO + +````md +# Component >> Calendar ||20 + +`lion-calendar` is a reusable and accessible calendar view. It depends on [calendar](../../path/to/calendar.md). + +```js script +import { html, css } from '@lion/core'; +import '@lion/calendar/define'; +``` + +... +```` + +So what you need to do: + +1. Remove the js default export and put the title / navigation into the headline +2. Replace all imports with the Package Entry Points +3. Adjust all link to be relative links to actual files (instead of storybook specific urls) + +## Upgrading Extending Documentation + +If you are currently extending our storybook documentation then this will no longer work. +For now we will need to ask you to stay on the current version and NOT upgrade. + +We will release the necessary tools to extend our Lion Website in the upcoming weeks 🤗 diff --git a/docs/blog/images/controlling-exports-cover-image.jpg b/docs/blog/images/controlling-exports-cover-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ed90497bada13c2750ecd9ca40e4ed0eabc99390 GIT binary patch literal 45081 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 T^; ``` -There we go, Lea's component is already done, so let's write some documentation. See the [live Lea tabs documentation page](?path=/docs/intro-tabs-example--default-story). You can see the full code of `lea-tabs` [on github](https://github.com/ing-bank/lion/tree/master/demo/). +There we go, Lea's component is already done, so let's write some documentation. See the [live Lea tabs documentation page](../components/content/tabs/examples.md). You can see the full code of `lea-tabs` [on github](https://github.com/ing-bank/lion/tree/master/demo/). P.S.: Do note that Lea is now responsible for keeping the documentation of `lea-tabs` up to date herself, and improvements on Lion's documentation will not automatically be reflected on Lea's documentation. @@ -223,7 +224,7 @@ Component libraries are in huge demand. By open-sourcing our extendable componen Building applications is hard, and sometimes, you need a little bit more than just the right component alone, but also things like: Validation, Forms, Overlays, Localization, etc. But fear not; Lion has got you covered! -You can check them out in our [documentation](http://lion-web-components.netlify.com/), and we'll go into more depth about Lion's additional systems in future blog posts. +You can check them out in our [documentation](http://lion-web.netlify.app/), and we'll go into more depth about Lion's additional systems in future blog posts. ## Thanks diff --git a/docs/blog/introducing-lions-website.md b/docs/blog/introducing-lions-website.md new file mode 100644 index 000000000..b78bd3865 --- /dev/null +++ b/docs/blog/introducing-lions-website.md @@ -0,0 +1,110 @@ +--- +title: Introducing lions website +published: true +description: A static website with docs and demos for lion +date: 2021-03-10 +tags: [javascript, rocket, documentation] +cover_image: /blog/images/introducing-lions-website-cover-image.jpg +--- + +After a month of preparations, we can finally present to you our new website. With it, we are enabled to give more context to each of our components. +Right now it's more or less a port for our existing demos from storybook. But we can organize it in a nicer way by splitting it into components, docs, guides and blog sections. + +## Meet the new sections + +1. [Guides](../guides/index.md)
    + A dedicated section where we will teach you about how to get started with lion. This section is completely new and will grow over time. +2. [Components](../components/index.md)
    + Here you will find our documentation for each of our components. Each is split into two pages namely Overview and Features. We also plan to add an API page soonish. +3. [Docs](../docs/index.md)
    + This is the home for general documentation which includes the fundamental systems all our components are build upon and various tools we use in the frontend or backend. +4. [Blog](./index.md)
    + We now have a dedicated section about all our blog posts. Take a peek and follow our story. + +## Upgrading Our Documentation + +As this page is now a static website and no longer storybook we needed to convert all our documentation. +Luckily the format is very similar. + +Let's convert an example page + +### FROM + +````md +# Calendar + +`lion-calendar` is a reusable and accessible calendar view. It depends on [calendar](?path=/docs/calendar--default-story). + +```js script +import { html, css } from '@lion/core'; +import './lion-calendar.js'; + +export default { + title: 'Others/Calendar', +}; +``` + +... +```` + +### TO + +````md +# Component >> Calendar ||20 + +`lion-calendar` is a reusable and accessible calendar view. It depends on [calendar](../../path/to/calendar.md). + +```js script +import { html, css } from '@lion/core'; +import '@lion/calendar/define'; +``` + +... +```` + +So what we needed to do: + +1. Remove the js default export and put the title / navigation into the headline +2. Replace all imports with the Package Entry Points +3. Adjust all link to be relative links to actual files (instead of storybook specific urls) + +## Handling Mono Repo Documentation + +All of our documentation now resides in the root `docs` folder. To publish them with our components we added a tool that can copy content and files into our published package. + +Let's say you have this file in your documentation. + +👉 `docs/components/accordion/overview.md` + +``` +# Accordion + +Is a very useful... +``` + +Now you want to make sure it gets published with your accordion package so you replace you Readme file with this + +👉 `packages/accordion/README.md` + +``` +# Accordion + +[=> See Source <=](../../docs/components/content/accordion/overview.md) +``` + +Now by calling `publish-docs` within the `prepublishOnly` step your Readme file will contain the content of its source. + +The benefits of this approach are + +- Readme still makes sense on GitHub (e.g. you can navigate to the package and with one click you are at the docs) +- The published readme contains all the documentation you need +- All links are version safe (e.g. if you look at v0.5 it will link to the GitHub Pages at this time) + +If you want to know more please look at the documentation for [publish-docs](../docs/node-tools/publish-docs/overview.md). + +## Upgrading Extending Documentation + +If you are currently extending our storybook documentation then this will no longer work. +For now, we will need to ask you to stay on the current version and NOT upgrade. + +We will release the necessary tools to extend our Lion Website in the upcoming weeks 🤗 diff --git a/docs/browserconfig.xml b/docs/browserconfig.xml new file mode 100644 index 000000000..549601dcd --- /dev/null +++ b/docs/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #1d3557 + + + diff --git a/docs/components/content/accordion/features.md b/docs/components/content/accordion/features.md new file mode 100644 index 000000000..a4d7535e2 --- /dev/null +++ b/docs/components/content/accordion/features.md @@ -0,0 +1,214 @@ +# Content >> Accordion >> Features ||20 + +```js script +import { LitElement, html } from '@lion/core'; + +import '@lion/accordion/define'; +``` + +## Expanded + +You can set `expanded` to pre-expand a certain invoker. + +```js preview-story +export const expanded = () => html` + +

    + +

    +

    Lorem ipsum dolor sit, amet consectetur adipisicing elit.

    +

    + +

    +

    + Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde + labore reiciendis saepe, iure, optio officiis obcaecati quibusdam. +

    +
    +`; +``` + +## Slots Order + +The invoker and content slots are ordered by DOM order. + +```js preview-story +export const slotsOrder = () => html` + +

    + +

    +

    Lorem ipsum dolor sit, amet consectetur adipisicing elit.

    +

    + +

    +

    + Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde + labore reiciendis saepe, iure, optio officiis obcaecati quibusdam. +

    +
    +`; +``` + +## Multiline header + +A header can be multiline. + +```js preview-story +export const multilineHeader = () => html` + +

    + +

    +

    content 1

    +

    + +

    +

    content 2

    +
    +`; +``` + +## Distribute New Elements + +Below, we demonstrate how you could dynamically add a new invoker + content. + +```js preview-story +export const distributeNewElement = () => { + const tagName = 'demo-accordion-add-dynamically'; + if (!customElements.get(tagName)) { + customElements.define( + tagName, + class extends LitElement { + static get properties() { + return { + __collection: { type: Array }, + }; + } + render() { + return html` +

    Append

    + +

    + +

    +

    content 1

    +

    + +

    +

    content 2

    +
    + +
    +

    Push

    + +

    + +

    +

    content 1

    +

    + +

    +

    content 2

    + ${this.__collection.map( + item => html` +

    +

    ${item.content}

    + `, + )} +
    + + `; + } + constructor() { + super(); + this.__collection = []; + } + __handleAppendClick() { + const accordionElement = this.shadowRoot.querySelector('#appendAccordion'); + const c = 2; + const n = Math.floor(accordionElement.children.length / 2); + for (let i = n + 1; i < n + c; i += 1) { + const invoker = document.createElement('h4'); + const button = document.createElement('button'); + button.innerText = `header ${i}`; + invoker.setAttribute('slot', 'invoker'); + invoker.appendChild(button); + const content = document.createElement('p'); + content.setAttribute('slot', 'content'); + content.innerText = `content ${i}`; + accordionElement.append(invoker); + accordionElement.append(content); + } + } + __handlePushClick() { + const accordionElement = this.shadowRoot.querySelector('#pushTabs'); + const i = Math.floor(accordionElement.children.length / 2) + 1; + this.__collection = [ + ...this.__collection, + { + invoker: `header ${i}`, + content: `content ${i}`, + }, + ]; + } + }, + ); + } + return html` `; +}; +``` + +One way is by creating the DOM elements and appending them as needed. + +Inside your `lion-accordion` extension, an example for appending nodes on a certain button click: + +```js +__handleAppendClick() { + const accordionAmount = this.children.length / 2; + const invoker = document.createElement('h4'); + const button = document.createElement('button'); + button.innerText = `header ${accordionAmount + 1}`; + invoker.setAttribute('slot', 'invoker'); + invoker.appendChild(button); + const content = document.createElement('p'); + content.setAttribute('slot', 'content'); + content.innerText = `content ${accordionAmount + 1}`; + this.append(invoker); + this.append(content); +} +``` + +The other way is by adding data to a Lit property where you loop over this property in your template. +You then need to ensure this causes a re-render. + +```js +__handlePushClick() { + const accordionAmount = this.children.length; + myCollection = [ + ...myCollection, + { + invoker: `header ${accordionAmount + 1}`, + content: `content ${accordionAmount + 1}`, + }, + ]; + renderMyCollection(); +} +``` + +Make sure your template re-renders when myCollection is updated. + +```html + + ${myCollection.map(item => html` +

    + +

    +

    ${item.content}

    + `)} +
    +``` diff --git a/docs/components/content/accordion/index.md b/docs/components/content/accordion/index.md new file mode 100644 index 000000000..cf0241b22 --- /dev/null +++ b/docs/components/content/accordion/index.md @@ -0,0 +1,3 @@ +# Content >> Accordion + +-> go to Overview diff --git a/docs/components/content/accordion/overview.md b/docs/components/content/accordion/overview.md new file mode 100644 index 000000000..e280f4a99 --- /dev/null +++ b/docs/components/content/accordion/overview.md @@ -0,0 +1,52 @@ +# Content >> Accordion >> Overview ||10 + +`lion-accordion` is a component used to toggle the display of sections of content. +Its purpose is to reduce the need to scroll when presenting multiple sections of content on a single page. Accordions often allow users to get the big picture before focusing on details. + +```js script +import { html } from '@lion/core'; +import '@lion/accordion/define'; +``` + +```js preview-story +export const main = () => html` + +

    + +

    +

    Lorem ipsum dolor sit, amet consectetur adipisicing elit.

    +

    + +

    +

    + Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde + labore reiciendis saepe, iure, optio officiis obcaecati quibusdam. +

    +
    +`; +``` + +## Features + +- content gets provided by users (slotted in) +- handles accessibility +- support navigation via keyboard + +## Installation + +```bash +npm i --save @lion/accordion +``` + +```js +import { LionAccordion } from '@lion/accordion'; +// or +import '@lion/accordion/define'; +``` + +## Rationale + +### Contents are not focusable + +Focusable elements should be interactive. Contents themselves do not offer any interactivity. +If there is a button or a form inside the tab panel then these elements get focused directly. diff --git a/packages/collapsible/demo/CustomCollapsible.js b/docs/components/content/collapsible/assets/CustomCollapsible.js similarity index 88% rename from packages/collapsible/demo/CustomCollapsible.js rename to docs/components/content/collapsible/assets/CustomCollapsible.js index dbfcde7d7..09df418b6 100644 --- a/packages/collapsible/demo/CustomCollapsible.js +++ b/docs/components/content/collapsible/assets/CustomCollapsible.js @@ -1,4 +1,4 @@ -import { LionCollapsible } from '../index.js'; +import { LionCollapsible } from '@lion/collapsible'; const EVENT = { TRANSITION_END: 'transitionend', @@ -8,8 +8,8 @@ const EVENT = { * `CustomCollapsible` is a class for custom collapsible element (`` web component). * @customElement custom-collapsible */ +// @ts-expect-error false positive for incompatible static get properties. Lit-element merges super properties already for you. export class CustomCollapsible extends LionCollapsible { - /** @type {any} */ static get properties() { return { transitioning: { @@ -56,9 +56,7 @@ export class CustomCollapsible extends LionCollapsible { contentNode.style.setProperty('opacity', '1'); contentNode.style.setProperty('padding', '12px 0'); contentNode.style.setProperty('max-height', '0px'); - await /** @type {Promise} */ (new Promise(resolve => - requestAnimationFrame(() => resolve()), - )); + await new Promise(resolve => requestAnimationFrame(() => resolve())); contentNode.style.setProperty('max-height', expectedHeight); await this._waitForTransition({ contentNode }); } @@ -107,9 +105,9 @@ export class CustomCollapsible extends LionCollapsible { */ async __calculateHeight(contentNode) { contentNode.style.setProperty('max-height', ''); - await /** @type {Promise} */ (new Promise(resolve => - requestAnimationFrame(() => resolve()), - )); + await new Promise(resolve => requestAnimationFrame(() => resolve())); return this._contentHeight; // Expected height i.e. actual size once collapsed after animation } } + +customElements.define('custom-collapsible', CustomCollapsible); diff --git a/packages/collapsible/demo/applyDemoCollapsibleStyles.js b/docs/components/content/collapsible/assets/applyDemoCollapsibleStyles.js similarity index 100% rename from packages/collapsible/demo/applyDemoCollapsibleStyles.js rename to docs/components/content/collapsible/assets/applyDemoCollapsibleStyles.js diff --git a/docs/components/content/collapsible/examples.md b/docs/components/content/collapsible/examples.md new file mode 100644 index 000000000..ef5708c9d --- /dev/null +++ b/docs/components/content/collapsible/examples.md @@ -0,0 +1,83 @@ +# Content >> Collapsible >> Examples ||30 + +```js script +import { html } from '@lion/core'; +import '@lion/collapsible/define'; +import '@lion/button/define'; +import './assets/CustomCollapsible.js'; +import './assets/applyDemoCollapsibleStyles.js'; +``` + +## Custom Invoker Template + +A custom template can be specified to the `invoker` slot. It can be any button or custom component which mimics the button behavior for better accessibility support. In the below example, `lion-button` and native `button` with styling is used as a collapsible invoker. + +```js preview-story +export const customInvokerTemplate = () => html` + + More about cars +
    + Most definitions of cars say that they run primarily on roads, seat one to eight people, have + four tires, and mainly transport people rather than goods. +
    +
    +`; +``` + +## Extended collapsible with animation + +`LionCollapsible` can easily be extended to add more features in the component, like animation for example. + +```js preview-story +export const customAnimation = () => html` +
    +
    + A motorcycle, often called a motorbike, bike, or cycle, is a two- or three-wheeled motor + vehicle. +
    + + +
    + Motorcycle design varies greatly to suit a range of different purposes: long distance + travel, commuting, cruising, sport including racing, and off-road riding. Motorcycling is + riding a motorcycle and related social activity such as joining a motorcycle club and + attending motorcycle rallies. +
    +
    +
    +
    +
    + A car (or automobile) is a wheeled motor vehicle used for transportation. +
    + + +
    + Most definitions of cars say that they run primarily on roads, seat one to eight people, + have four tires, and mainly transport people rather than goods. +
    +
    +
    +`; +``` + +Use `_showAnimation()` and `_hideAnimation()` methods to customize open and close behavior. Check the code for a full example of a `custom-collapsible`. + +```js +_showAnimation({ contentNode }) { + const expectedHeight = await this.__calculateHeight(contentNode); + contentNode.style.setProperty('opacity', '1'); + contentNode.style.setProperty('padding', '12px 0'); + contentNode.style.setProperty('max-height', '0px'); + await new Promise(resolve => requestAnimationFrame(() => resolve())); + contentNode.style.setProperty('max-height', expectedHeight); + await this._waitForTransition({ contentNode }); +} + +_hideAnimation({ contentNode }) { + if (this._contentHeight === '0px') { + return; + } + ['opacity', 'padding', 'max-height'].map(prop => contentNode.style.setProperty(prop, 0)); + await this._waitForTransition({ contentNode }); +} +``` diff --git a/docs/components/content/collapsible/features.md b/docs/components/content/collapsible/features.md new file mode 100644 index 000000000..b8f569000 --- /dev/null +++ b/docs/components/content/collapsible/features.md @@ -0,0 +1,79 @@ +# Content >> Collapsible >> Features ||20 + +```js script +import { html } from '@lion/core'; +import '@lion/collapsible/define'; +``` + +## Default open + +Add the `opened` attribute to keep the component default open. + +```js preview-story +export const defaultOpen = () => html` + + +
    + Most definitions of cars say that they run primarily on roads, seat one to eight people, have + four tires, and mainly transport people rather than goods. +
    +
    +`; +``` + +## Methods + +There are the following methods available to control the extra content for the collapsible. + +- `toggle()`: toggle the extra content +- `show()`: show the extra content +- `hide()`: hide the extra content + +```js preview-story +export const methods = ({ shadowRoot }) => html` + + +
    + Most definitions of cars say that they run primarily on roads, seat one to eight people, have + four tires, and mainly transport people rather than goods. +
    +
    +
    + + + +
    +`; +``` + +## Events + +`lion-collapsible` fires an event on `invoker` click to notify the component's current state. It is useful for analytics purposes or to perform some actions while expanding and collapsing the component. + +- `@opened-changed`: triggers when collapsible either gets opened or closed + +```js preview-story +export const events = ({ shadowRoot }) => html` +
    + +
    + { + const collapsibleState = shadowRoot.getElementById('collapsible-state'); + collapsibleState.innerText = `Opened: ${ev.target.opened}`; + }} + > + +
    + Most definitions of cars say that they run primarily on roads, seat one to eight people, have + four tires, and mainly transport people rather than goods. +
    +
    +`; +``` diff --git a/docs/components/content/collapsible/index.md b/docs/components/content/collapsible/index.md new file mode 100644 index 000000000..f15486238 --- /dev/null +++ b/docs/components/content/collapsible/index.md @@ -0,0 +1,3 @@ +# Content >> Collapsible + +-> go to Overview diff --git a/docs/components/content/collapsible/overview.md b/docs/components/content/collapsible/overview.md new file mode 100644 index 000000000..802359176 --- /dev/null +++ b/docs/components/content/collapsible/overview.md @@ -0,0 +1,39 @@ +# Content >> Collapsible >> Overview ||10 + +`lion-collapsible` is a combination of a button (the invoker), a chunk of 'extra content', and can be extended with an animation to disclose the extra content. There are two slots available respectively; `invoker` to specify the collapsible's invoker and `content` for the extra content of the collapsible. + +```js script +import { html } from '@lion/core'; +import '@lion/collapsible/define'; +``` + +```js preview-story +export const main = () => html` + + +
    + Most definitions of cars say that they run primarily on roads, seat one to eight people, have + four tires, and mainly transport people rather than goods. +
    +
    +`; +``` + +## Features + +- Use `opened` attribute or `toggle()` method to render default open +- `invoker` slot can be custom template e.g. `lion-button` or native `button` with custom styling +- Observe the state with the help of `@opened-changed` event +- `show()` and `hide()` are helper methods to hide or show the content from outside + +## Installation + +```bash +npm i --save @lion/collapsible +``` + +```js +import { LionCollapsible } from '@lion/collapsible'; +// or +import '@lion/collapsible/define'; +``` diff --git a/docs/components/content/index.md b/docs/components/content/index.md new file mode 100644 index 000000000..deae6f052 --- /dev/null +++ b/docs/components/content/index.md @@ -0,0 +1 @@ +# Content ||10 diff --git a/packages/progress-indicator/demo/CustomProgressIndicator.js b/docs/components/content/progress-indicator/assets/custom-progress-indicator.js similarity index 65% rename from packages/progress-indicator/demo/CustomProgressIndicator.js rename to docs/components/content/progress-indicator/assets/custom-progress-indicator.js index 85fc4d1c5..da27c83ec 100644 --- a/packages/progress-indicator/demo/CustomProgressIndicator.js +++ b/docs/components/content/progress-indicator/assets/custom-progress-indicator.js @@ -1,26 +1,26 @@ -import { svg, css } from '@lion/core'; -import { LionProgressIndicator } from '../index.js'; +import { html, css } from '@lion/core'; +import { LionProgressIndicator } from '@lion/progress-indicator'; export class CustomProgressIndicator extends LionProgressIndicator { static get styles() { return [ css` :host { - display: inline-block; + display: block; } - svg { - animation: spinner-rotate 2s linear infinite; + .progress--icon { display: inline-block; - height: 48px; width: 48px; + height: 48px; + animation: spinner-rotate 2s linear infinite; } - circle { + .progress--icon--circle { animation: spinner-dash 1.35s ease-in-out infinite; fill: none; - stroke-width: 3.6; - stroke: firebrick; + stroke-width: 6px; + stroke: var(--primary-color); stroke-dasharray: 100, 28; /* This is a fallback for IE11 */ } @@ -49,8 +49,12 @@ export class CustomProgressIndicator extends LionProgressIndicator { } _graphicTemplate() { - return svg` - - `; + return html` + + + + `; } } + +customElements.define('custom-progress-indicator', CustomProgressIndicator); diff --git a/docs/components/content/progress-indicator/examples.md b/docs/components/content/progress-indicator/examples.md new file mode 100644 index 000000000..3baa49193 --- /dev/null +++ b/docs/components/content/progress-indicator/examples.md @@ -0,0 +1,76 @@ +# Content >> Progress Indicator >> Examples ||30 + +```js script +import { html } from '@lion/core'; +import './assets/custom-progress-indicator.js'; +``` + +## Extended indicator with a custom visual + +`LionProgressIndicator` is designed to be extended to add visuals. Implement the `_graphicTemplate()` method to set the rendered content and apply styles normally. + +### Example extension + +```js +class CustomProgressIndicator extends LionProgressIndicator { + static get styles() { + return [ + css` + :host { + display: block; + } + + .progress--icon { + display: inline-block; + width: 48px; + height: 48px; + animation: spinner-rotate 2s linear infinite; + } + + .progress--icon--circle { + animation: spinner-dash 1.35s ease-in-out infinite; + fill: none; + stroke-width: 6px; + stroke: var(--primary-color); + stroke-dasharray: 100, 28; /* This is a fallback for IE11 */ + } + + @keyframes spinner-rotate { + to { + transform: rotate(360deg); + } + } + + @keyframes spinner-dash { + 0% { + stroke-dasharray: 6, 122; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 100, 28; + stroke-dashoffset: -16; + } + 100% { + stroke-dasharray: 6, 122; + stroke-dashoffset: -127; + } + } + `, + ]; + } + + _graphicTemplate() { + return html` + + + + `; + } +} +``` + +### Result + +```js preview-story +export const main = () => html` `; +``` diff --git a/docs/components/content/progress-indicator/index.md b/docs/components/content/progress-indicator/index.md new file mode 100644 index 000000000..3180953cb --- /dev/null +++ b/docs/components/content/progress-indicator/index.md @@ -0,0 +1,3 @@ +# Content >> Progress Indicator + +-> go to Overview diff --git a/docs/components/content/progress-indicator/overview.md b/docs/components/content/progress-indicator/overview.md new file mode 100644 index 000000000..7ad6689ad --- /dev/null +++ b/docs/components/content/progress-indicator/overview.md @@ -0,0 +1,29 @@ +# Content >> Progress Indicator >> Overview ||10 + +`lion-progress-indicator` implements accessibility requirements for progress indicators. + +```html + +``` + +Note: You don't see a live demo here as it would be empty, since there is no styling. Check out the [examples](./examples.md) if you want to see a possible implementation. + +## Features + +`LionProgressIndicator` is designed to be extended to add visuals. + +- Accessibility compliant +- Localized "Loading" label +- Implementation independent of visuals + +## Installation + +```bash +npm i --save @lion/progress-indicator +``` + +```js +import { LionProgressIndicator } from '@lion/progress-indicator'; +// or +import '@lion/progress-indicator/define'; +``` diff --git a/docs/components/content/tabs/examples.md b/docs/components/content/tabs/examples.md new file mode 100644 index 000000000..f9c46d068 --- /dev/null +++ b/docs/components/content/tabs/examples.md @@ -0,0 +1,23 @@ +# Content >> Tabs >> Examples ||30 + +```js script +import { LitElement, html } from '@lion/core'; +import './src/lea-tabs.js'; +import './src/lea-tab.js'; +import './src/lea-tab-panel.js'; +``` + +## Lea Tabs + +Learn how to create the `lea tabs` in our ["introducing lion" blogpost](../../../blog/ing-open-sources-lion.md). + +```js preview-story +export const main = () => html` + + Info + Info page with lots of information about us. + Work + Work page that showcases our work. + +`; +``` diff --git a/docs/components/content/tabs/features.md b/docs/components/content/tabs/features.md new file mode 100644 index 000000000..79b42ea5d --- /dev/null +++ b/docs/components/content/tabs/features.md @@ -0,0 +1,194 @@ +# Content >> Tabs >> Features ||20 + +```js script +import { LitElement, html } from '@lion/core'; + +import '@lion/tabs/define'; +``` + +## Selected Index + +You can set the `selectedIndex` to select a certain tab. + +```js preview-story +export const selectedIndex = () => html` + + +

    Info page with lots of information about us.

    + +

    Work page that showcases our work.

    +
    +`; +``` + +## Slots Order + +The tab and panel slots are ordered by DOM order. + +This means you can switch the grouping in your `lion-tabs` from tab + panel to all tabs first or all panels first. + +```js preview-story +export const slotsOrder = () => html` + + + +

    Info page with lots of information about us.

    +

    Work page that showcases our work.

    +
    +`; +``` + +## Nesting tabs + +You can include tabs within tabs + +```js preview-story +export const nestedTabs = () => html` + + + +
    +

    Find some more info about our favorite movies:

    + + + +

    + Cars is a 2006 American computer-animated comedy film produced by Pixar Animation Studios + and released by Walt Disney Pictures. +

    +

    + The feature film directorial debut of John Lasseter, it was the first entirely + computer-animated feature film, as well as the first feature film from Pixar. +

    +
    +
    +

    Work page that showcases our work.

    +
    +`; +``` + +## Distribute New Elements + +Below, we demonstrate on how you could dynamically add new tab + panels. + +```js preview-story +export const distributeNewElement = () => { + const tagName = 'demo-tabs-add-dynamically'; + if (!customElements.get(tagName)) { + customElements.define( + tagName, + class extends LitElement { + static get properties() { + return { + __collection: { type: Array }, + }; + } + render() { + return html` +

    Append

    + + +

    panel 1

    + +

    panel 2

    +
    + +
    +

    Push

    + + +

    panel 1

    + +

    panel 2

    + ${this.__collection.map( + item => html` + +

    ${item.panel}

    + `, + )} +
    + + `; + } + constructor() { + super(); + this.__collection = []; + } + __handleAppendClick() { + const tabsElement = this.shadowRoot.querySelector('#appendTabs'); + const c = 2; + const n = Math.floor(tabsElement.children.length / 2); + for (let i = n + 1; i < n + c; i += 1) { + const tab = document.createElement('button'); + tab.setAttribute('slot', 'tab'); + tab.innerText = `tab ${i}`; + const panel = document.createElement('p'); + panel.setAttribute('slot', 'panel'); + panel.innerText = `panel ${i}`; + tabsElement.append(tab); + tabsElement.append(panel); + } + } + __handlePushClick() { + const tabsElement = this.shadowRoot.querySelector('#pushTabs'); + const i = Math.floor(tabsElement.children.length / 2) + 1; + this.__collection = [ + ...this.__collection, + { + button: `tab ${i}`, + panel: `panel ${i}`, + }, + ]; + } + }, + ); + } + return html` `; +}; +``` + +One way is by creating the DOM elements and appending them as needed. + +Inside your `lion-tabs` extension, an example for appending nodes on a certain button click: + +```js +__handleAppendClick() { + const tabsAmount = this.children.length / 2; + const tab = document.createElement('button'); + tab.setAttribute('slot', 'tab'); + tab.innerText = `tab ${tabsAmount + 1}`; + const panel = document.createElement('p'); + panel.setAttribute('slot', 'panel'); + panel.innerText = `panel ${tabsAmount + 1}`; + this.append(tab); + this.append(panel); +} +``` + +The other way is by adding data to a Lit property where you loop over this property in your template. +You then need to ensure this causes a re-render. + +```js +__handlePushClick() { + const tabsAmount = this.children.length; + myCollection = [ + ...myCollection, + { + button: `tab ${tabsAmount + 1}`, + panel: `panel ${tabsAmount + 1}`, + }, + ]; + renderMyCollection(); +} +``` + +Make sure your template re-renders when myCollection is updated. + +```html + + ${myCollection.map(item => html` + +

    ${item.panel}

    + `)} +
    +``` diff --git a/docs/components/content/tabs/index.md b/docs/components/content/tabs/index.md new file mode 100644 index 000000000..3018ec15e --- /dev/null +++ b/docs/components/content/tabs/index.md @@ -0,0 +1,3 @@ +# Content >> Tabs + +-> go to Overview diff --git a/docs/components/content/tabs/overview.md b/docs/components/content/tabs/overview.md new file mode 100644 index 000000000..747013b01 --- /dev/null +++ b/docs/components/content/tabs/overview.md @@ -0,0 +1,48 @@ +# Content >> Tabs >> Overview ||10 + +A component to allow users to quickly move between a small number of equally important views. + +```js script +import { LitElement, html } from '@lion/core'; +import '@lion/tabs/define'; +``` + +```js preview-story +export const main = () => html` + + +

    Info page with lots of information about us.

    + +

    Work page that showcases our work.

    +
    +`; +``` + +## Installation + +```bash +npm i --save @lion/tabs; +``` + +```js +import { LionTabs } from '@lion/tabs'; +// or +import '@lion/tabs/define'; +``` + +## Rationale + +### No separate active/focus state when using keyboard + +We will immediately switch content as all our content comes from light dom (e.g. no latency) + +See Note at + +> It is recommended that tabs activate automatically when they receive focus as long as their +> associated tab panels are displayed without noticeable latency. This typically requires tab +> panel content to be preloaded. + +### Panels are not focusable + +Focusable elements should have a means to interact with them. Tab panels themselves do not offer any interactivity. +If there is a button or a form inside the tab panel then these elements get focused directly. diff --git a/demo/src/LeaTabPanel.js b/docs/components/content/tabs/src/lea-tab-panel.js similarity index 89% rename from demo/src/LeaTabPanel.js rename to docs/components/content/tabs/src/lea-tab-panel.js index 993461a19..3584d24a5 100644 --- a/demo/src/LeaTabPanel.js +++ b/docs/components/content/tabs/src/lea-tab-panel.js @@ -20,3 +20,5 @@ export class LeaTabPanel extends LitElement { `; } } + +customElements.define('lea-tab-panel', LeaTabPanel); diff --git a/demo/src/LeaTab.js b/docs/components/content/tabs/src/lea-tab.js similarity index 96% rename from demo/src/LeaTab.js rename to docs/components/content/tabs/src/lea-tab.js index b43d5944f..64b6940c7 100644 --- a/demo/src/LeaTab.js +++ b/docs/components/content/tabs/src/lea-tab.js @@ -41,3 +41,5 @@ export class LeaTab extends LitElement { return html``; } } + +customElements.define('lea-tab', LeaTab); diff --git a/demo/src/LeaTabs.js b/docs/components/content/tabs/src/lea-tabs.js similarity index 90% rename from demo/src/LeaTabs.js rename to docs/components/content/tabs/src/lea-tabs.js index aa81386a7..3c3f385a0 100644 --- a/demo/src/LeaTabs.js +++ b/docs/components/content/tabs/src/lea-tabs.js @@ -24,3 +24,5 @@ export class LeaTabs extends LionTabs { // being awesome } } + +customElements.define('lea-tabs', LeaTabs); diff --git a/packages/icon/docs/icons/bugs/bug01.svg.js b/docs/components/icons/icon/assets/bugs/bug01.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug01.svg.js rename to docs/components/icons/icon/assets/bugs/bug01.svg.js diff --git a/packages/icon/docs/icons/bugs/bug02.svg.js b/docs/components/icons/icon/assets/bugs/bug02.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug02.svg.js rename to docs/components/icons/icon/assets/bugs/bug02.svg.js diff --git a/packages/icon/docs/icons/bugs/bug05.svg.js b/docs/components/icons/icon/assets/bugs/bug05.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug05.svg.js rename to docs/components/icons/icon/assets/bugs/bug05.svg.js diff --git a/packages/icon/docs/icons/bugs/bug06.svg.js b/docs/components/icons/icon/assets/bugs/bug06.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug06.svg.js rename to docs/components/icons/icon/assets/bugs/bug06.svg.js diff --git a/packages/icon/docs/icons/bugs/bug08.svg.js b/docs/components/icons/icon/assets/bugs/bug08.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug08.svg.js rename to docs/components/icons/icon/assets/bugs/bug08.svg.js diff --git a/packages/icon/docs/icons/bugs/bug12.svg.js b/docs/components/icons/icon/assets/bugs/bug12.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug12.svg.js rename to docs/components/icons/icon/assets/bugs/bug12.svg.js diff --git a/packages/icon/docs/icons/bugs/bug19.svg.js b/docs/components/icons/icon/assets/bugs/bug19.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug19.svg.js rename to docs/components/icons/icon/assets/bugs/bug19.svg.js diff --git a/packages/icon/docs/icons/bugs/bug23.svg.js b/docs/components/icons/icon/assets/bugs/bug23.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug23.svg.js rename to docs/components/icons/icon/assets/bugs/bug23.svg.js diff --git a/packages/icon/docs/icons/bugs/bug24.svg.js b/docs/components/icons/icon/assets/bugs/bug24.svg.js similarity index 100% rename from packages/icon/docs/icons/bugs/bug24.svg.js rename to docs/components/icons/icon/assets/bugs/bug24.svg.js diff --git a/packages/icon/docs/icons/iconset-bugs.js b/docs/components/icons/icon/assets/iconset-bugs.js similarity index 100% rename from packages/icon/docs/icons/iconset-bugs.js rename to docs/components/icons/icon/assets/iconset-bugs.js diff --git a/packages/icon/docs/icons/iconset-misc.js b/docs/components/icons/icon/assets/iconset-misc.js similarity index 100% rename from packages/icon/docs/icons/iconset-misc.js rename to docs/components/icons/icon/assets/iconset-misc.js diff --git a/packages/icon/docs/icons/iconset-space.js b/docs/components/icons/icon/assets/iconset-space.js similarity index 100% rename from packages/icon/docs/icons/iconset-space.js rename to docs/components/icons/icon/assets/iconset-space.js diff --git a/packages/icon/docs/icons/misc/arrowLeft.svg.js b/docs/components/icons/icon/assets/misc/arrowLeft.svg.js similarity index 100% rename from packages/icon/docs/icons/misc/arrowLeft.svg.js rename to docs/components/icons/icon/assets/misc/arrowLeft.svg.js diff --git a/packages/icon/docs/icons/space/aliens-spaceship.svg.js b/docs/components/icons/icon/assets/space/aliens-spaceship.svg.js similarity index 100% rename from packages/icon/docs/icons/space/aliens-spaceship.svg.js rename to docs/components/icons/icon/assets/space/aliens-spaceship.svg.js diff --git a/packages/icon/docs/icons/space/meteor.svg.js b/docs/components/icons/icon/assets/space/meteor.svg.js similarity index 100% rename from packages/icon/docs/icons/space/meteor.svg.js rename to docs/components/icons/icon/assets/space/meteor.svg.js diff --git a/packages/icon/docs/icons/space/moon-flag.svg.js b/docs/components/icons/icon/assets/space/moon-flag.svg.js similarity index 100% rename from packages/icon/docs/icons/space/moon-flag.svg.js rename to docs/components/icons/icon/assets/space/moon-flag.svg.js diff --git a/packages/icon/docs/icons/space/moon.svg.js b/docs/components/icons/icon/assets/space/moon.svg.js similarity index 100% rename from packages/icon/docs/icons/space/moon.svg.js rename to docs/components/icons/icon/assets/space/moon.svg.js diff --git a/packages/icon/docs/icons/space/night.svg.js b/docs/components/icons/icon/assets/space/night.svg.js similarity index 100% rename from packages/icon/docs/icons/space/night.svg.js rename to docs/components/icons/icon/assets/space/night.svg.js diff --git a/packages/icon/docs/icons/space/orbit.svg.js b/docs/components/icons/icon/assets/space/orbit.svg.js similarity index 100% rename from packages/icon/docs/icons/space/orbit.svg.js rename to docs/components/icons/icon/assets/space/orbit.svg.js diff --git a/packages/icon/docs/icons/space/planet.svg.js b/docs/components/icons/icon/assets/space/planet.svg.js similarity index 100% rename from packages/icon/docs/icons/space/planet.svg.js rename to docs/components/icons/icon/assets/space/planet.svg.js diff --git a/packages/icon/docs/icons/space/robot.svg.js b/docs/components/icons/icon/assets/space/robot.svg.js similarity index 100% rename from packages/icon/docs/icons/space/robot.svg.js rename to docs/components/icons/icon/assets/space/robot.svg.js diff --git a/packages/icon/docs/icons/space/rocket.svg.js b/docs/components/icons/icon/assets/space/rocket.svg.js similarity index 100% rename from packages/icon/docs/icons/space/rocket.svg.js rename to docs/components/icons/icon/assets/space/rocket.svg.js diff --git a/packages/icon/docs/icons/space/satellite.svg.js b/docs/components/icons/icon/assets/space/satellite.svg.js similarity index 100% rename from packages/icon/docs/icons/space/satellite.svg.js rename to docs/components/icons/icon/assets/space/satellite.svg.js diff --git a/packages/icon/docs/icons/space/signal.svg.js b/docs/components/icons/icon/assets/space/signal.svg.js similarity index 100% rename from packages/icon/docs/icons/space/signal.svg.js rename to docs/components/icons/icon/assets/space/signal.svg.js diff --git a/packages/icon/docs/icons/space/space-helmet.svg.js b/docs/components/icons/icon/assets/space/space-helmet.svg.js similarity index 100% rename from packages/icon/docs/icons/space/space-helmet.svg.js rename to docs/components/icons/icon/assets/space/space-helmet.svg.js diff --git a/packages/icon/docs/icons/space/sun.svg.js b/docs/components/icons/icon/assets/space/sun.svg.js similarity index 100% rename from packages/icon/docs/icons/space/sun.svg.js rename to docs/components/icons/icon/assets/space/sun.svg.js diff --git a/packages/icon/docs/icons/space/telescope.svg.js b/docs/components/icons/icon/assets/space/telescope.svg.js similarity index 100% rename from packages/icon/docs/icons/space/telescope.svg.js rename to docs/components/icons/icon/assets/space/telescope.svg.js diff --git a/docs/components/icons/icon/features.md b/docs/components/icons/icon/features.md new file mode 100644 index 000000000..1bf59957d --- /dev/null +++ b/docs/components/icons/icon/features.md @@ -0,0 +1,93 @@ +# Icons >> Icon >> Features ||20 + +```js script +import { html } from '@lion/core'; +import { icons } from '@lion/icon'; +import './assets/iconset-bugs.js'; +import './assets/iconset-misc.js'; +import * as spaceSet from './assets/iconset-space.js'; + +import '@lion/icon/define'; + +icons.addIconResolver('lion', (iconset, name) => { + switch (iconset) { + case 'bugs': + return import('./assets/iconset-bugs.js').then(module => module[name]); + case 'space': + return import('./assets/iconset-space.js').then(module => module[name]); + case 'misc': + return import('./assets/iconset-misc.js').then(module => module[name]); + default: + throw new Error(`Unknown iconset ${iconset}`); + } +}); +``` + +## Icon sets + +Icons are displayed using icon sets. These are collections of icons, lazily loaded on demand for performance. +See the [system documentation](../../../docs/systems/icon/overview.md) to learn more about icon sets. + +```js preview-story +export const iconSets = () => html` + ${Object.keys(spaceSet).map( + name => html` + +
    + + ${name} +
    + `, + )} +`; +``` + +If for some reason you don't want to lazy load icons, you can still import and use them +synchronously. + +## Accessibility + +It is recommended to add an `aria-label` to provide information to visually impaired users: + +A `lion-icon` without an `aria-label` attribute will be automatically given an `aria-hidden` attribute. + +```js preview-story +export const accessibleLabel = () => html` + +`; +``` + +## Styling + +By default, a `lion-icon` will be `1em` × `1em` (the current line-height). + +`lion-icon` uses SVGs and may be styled with CSS, including using CSS properties such as `fill`: + +```js preview-story +export const Styling = () => html` + + +`; +``` + +See [SVG and CSS](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/SVG_and_CSS) on MDN web docs for more information. diff --git a/docs/components/icons/icon/index.md b/docs/components/icons/icon/index.md new file mode 100644 index 000000000..0642be966 --- /dev/null +++ b/docs/components/icons/icon/index.md @@ -0,0 +1,3 @@ +# Icons >> Icon + +-> go to Overview diff --git a/docs/components/icons/icon/overview.md b/docs/components/icons/icon/overview.md new file mode 100644 index 000000000..48a4902ab --- /dev/null +++ b/docs/components/icons/icon/overview.md @@ -0,0 +1,40 @@ +# Icons >> Icon >> Overview ||10 + +A web component for displaying icons. + +```js script +import { html } from '@lion/core'; +import { icons } from '@lion/icon'; +import '@lion/icon/define'; + +icons.addIconResolver('lion', (iconset, name) => { + switch (iconset) { + case 'bugs': + return import('./assets/iconset-bugs.js').then(module => module[name]); + case 'space': + return import('./assets/iconset-space.js').then(module => module[name]); + case 'misc': + return import('./assets/iconset-misc.js').then(module => module[name]); + default: + throw new Error(`Unknown iconset ${iconset}`); + } +}); +``` + +```js preview-story +export const main = () => html` + +`; +``` + +## Installation + +```bash +npm i --save @lion/icon +``` + +```js +import { LionIcon } from '@lion/icon'; +// or +import '@lion/icon/define'; +``` diff --git a/docs/components/icons/index.md b/docs/components/icons/index.md new file mode 100644 index 000000000..71654445e --- /dev/null +++ b/docs/components/icons/index.md @@ -0,0 +1 @@ +# Icons ||30 diff --git a/docs/components/index.md b/docs/components/index.md new file mode 100644 index 000000000..a2a9287a0 --- /dev/null +++ b/docs/components/index.md @@ -0,0 +1,16 @@ +# Components ||20 + +We offer many web components for your application needs. For each, you will find an overview page to highlight its capabilities and how to start using it. Additionally, there will be a features page that showcases multiple use cases in action. Some even have a dedicated examples page so you can see a possible styled implementation. + +For organizational purposes, we split them into the following groups. + +1. [Content](./content/accordion/overview.md)
    + Everything to help you organize your content. +2. [Icons](./icons/icon/overview.md)
    + Loading and displaying icons. +3. [Inputs](./inputs/overview.md)
    + Input components that lets you make complex forms with ease, including validation. +4. [Interaction](./interaction/button/overview.md)
    + A set of interactive components. +5. [Navigation](./navigation/pagination/overview.md)
    + The reasoning behind some of our decisions. diff --git a/docs/components/inputs/calendar/features.md b/docs/components/inputs/calendar/features.md new file mode 100644 index 000000000..470c2edf4 --- /dev/null +++ b/docs/components/inputs/calendar/features.md @@ -0,0 +1,192 @@ +# Inputs >> Calendar >> Features ||20 + +```js script +import { html, css } from '@lion/core'; +import '@lion/calendar/define'; +``` + +## Selected date + +The `selectedDate` is the date which is currently marked as selected. +You usually select a date by clicking on it with the mouse or hitting Enter on the keyboard. + +The `selectedDate` might not be within the dates in the current month view. + +```js preview-story +export const selectedDate = () => html` + + +`; +``` + +## Central Date + +The `centralDate` defines which day will be focused when keyboard moves the focus to the current month grid. +By default it is set to today, or the enabled day of the current month view that is closest to today's date. + +The next and previous months' buttons work by changing the `centralDate` with plus or minus one month. +Changing the `centralDate` may mean a different view will be displayed to your users if it is in a different month. +Usually if you change only the day, "nothing" happens as it's already currently in view. + +The `centralDate` can be different from `selectedDate` as you can have today as actively selected but still look at date that is years ago. +When the `selectedDate` changes, it will sync its value to the `centralDate`. + +```js preview-story +export const centralDate = () => { + const today = new Date(); + const centralDate = new Date(today.getFullYear(), today.getMonth() + 1, today.getDate()); + return html` + + + `; +}; +``` + +## Controlling focus + +You can control the focus by calling the following methods + +- `focusCentralDate()` +- `focusSelectedDate()` +- `focusDate(dateInstanceToFocus)` + +> Be aware that the central date changes when a new date is focused. + +```js preview-story +export const controllingFocus = () => { + const today = new Date(); + const selectedDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1); + const centralDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 5); + return html` + + + + + + `; +}; +``` + +## Limiting selectable values + +### Providing a lower limit + +To give a lower limit you can bind a date to the `minDate` property. + +```js preview-story +export const providingLowerLimit = () => { + const minDate = new Date(); + return html` + + + `; +}; +``` + +### Provide a higher limit + +To give a higher limit you can bind a date to the `maxDate` property. In this example, we show how to create an offset of + 2 days. + +```js preview-story +export const providingHigherLimit = () => { + const today = new Date(); + const maxDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 2); + return html` + + + `; +}; +``` + +### Provide a list of disabled dates + +In some cases a specific date or day of the week needs to be disabled, supply those days to the `disableDates` property. + +```js preview-story +export const disabledDates = () => html` + + day.getDay() === 6 || day.getDay() === 0} + > +`; +``` + +### Combined disable dates + +To limit the scope of possible dates further, combine the methods mentioned above. + +```js preview-story +export const combinedDisabledDates = () => { + const today = new Date(); + const maxDate = new Date(today.getFullYear(), today.getMonth() + 2, today.getDate()); + return html` + + day.getDay() === 6 || day.getDay() === 0} + .minDate="${new Date()}" + .maxDate="${maxDate}" + > + `; +}; +``` diff --git a/docs/components/inputs/calendar/index.md b/docs/components/inputs/calendar/index.md new file mode 100644 index 000000000..1e2b998ea --- /dev/null +++ b/docs/components/inputs/calendar/index.md @@ -0,0 +1,3 @@ +# Inputs >> Calendar ||20 + +-> go to Overview diff --git a/docs/components/inputs/calendar/overview.md b/docs/components/inputs/calendar/overview.md new file mode 100644 index 000000000..cdec4e2ba --- /dev/null +++ b/docs/components/inputs/calendar/overview.md @@ -0,0 +1,49 @@ +# Inputs >> Calendar >> Overview ||10 + +`lion-calendar` is a reusable and accessible calendar view. + +```js script +import { html, css } from '@lion/core'; +import '@lion/calendar/define'; +``` + +```js story +export const main = () => { + return html` + + + `; +}; +``` + +## Features + +- fully accessible keyboard navigation (Arrow Keys, PgUp, PgDn, ALT+PgUp, ALT+PgDn) +- **minDate**: disables all dates before a given date +- **maxDate**: disables all dates after a given date +- **disableDates**: disables some dates within an available range +- **selectedDate**: currently selected date +- **centralDate**: date that determines the currently visible month and that will be focused when keyboard moves the focus to the month grid +- **focusedDate**: (getter only) currently focused date (if there is any with real focus) +- **focusDate(date)**: focus on a certain date +- **focusSelectedDate()**: focus on the current selected date +- **focusCentralDate()**: focus on the current central date +- **firstDayOfWeek**: typically Sunday (default) or Monday +- **weekdayHeaderNotation**: long/short/narrow for the current locale (e.g. Thursday/Thu/T) +- **locale**: different locale for the current component only + +## Installation + +```bash +npm i --save @lion/calendar +``` + +```js +import '@lion/calendar/define'; +``` diff --git a/docs/components/inputs/checkbox-group/features.md b/docs/components/inputs/checkbox-group/features.md new file mode 100644 index 000000000..6274421a2 --- /dev/null +++ b/docs/components/inputs/checkbox-group/features.md @@ -0,0 +1,205 @@ +# Inputs >> Checkbox Group >> Features ||20 + +```js script +import { html } from '@lion/core'; +import '@lion/checkbox-group/define'; +import '@lion/checkbox-group/define'; +import '@lion/checkbox-group/define'; +``` + +## Model value + +The `modelValue` of a `lion-checkbox-group` is an array containing the `choiceValues` of the `lion-checkbox` elements that have been checked. + +Given the scientists example above, say that we were to select the first and last options +(Archimedes & Marie Curie). + +Then the `modelValue` of the `lion-checkbox-group` will look as follows: + +```js +const groupElement = [parent].querySelector('lion-checkbox-group'); +groupElement.modelValue; + => ["Archimedes", "Marie Curie"]; +``` + +## The `name` attribute + +The `name` attribute of a `lion-checkbox-group` automatically gets assigned to its `lion-checkbox` children. You can also specify names for the `lion-checkbox` elements, but if this name is different from the name assigned to `lion-checkbox-group`, then an exception will be thrown. + +Our recommendation would be to set the `name` attribute only on the `lion-checkbox-group` and not on the `lion-checkbox` elements. + +## Example + +```html + + + + + +``` + +## Pre-select + +You can pre-select options by targeting the `modelValue` object of the option and setting the `checked` property to `true`. + +```js preview-story +export const preselect = () => html` + + + + + +`; +``` + +## Disabled + +You can disable the entire group by setting the `disabled` attribute on the ``. + +```js preview-story +export const disabled = () => html` + + + + + +`; +``` + +## Help text + +You can add help text on each checkbox with `help-text` attribute on the ``. + +```js preview-story +export const helpText = () => html` + + + + + +`; +``` + +## Event + +You can listen to the `model-value-changed` event whenever the value of the checkbox group is changed. + +```js preview-story +export const event = ({ shadowRoot }) => html` + + (shadowRoot.getElementById('selectedDinosaur').innerText = JSON.stringify( + ev.target.modelValue, + null, + 4, + ))} + > + + + + +
    + Selected scientists: N/A +`; +``` + +## Indeterminate + +```js preview-story +export const indeterminate = () => html` + + + + + + + +`; +``` + +```js preview-story +export const indeterminateSiblings = () => html` + + + + + + + + + + + +`; +``` + +```js preview-story +export const indeterminateChildren = () => html` + + + + + + + + + + + +`; +``` diff --git a/docs/components/inputs/checkbox-group/index.md b/docs/components/inputs/checkbox-group/index.md new file mode 100644 index 000000000..a5862f14b --- /dev/null +++ b/docs/components/inputs/checkbox-group/index.md @@ -0,0 +1,3 @@ +# Inputs >> Checkbox Group ||20 + +-> go to Overview diff --git a/docs/components/inputs/checkbox-group/overview.md b/docs/components/inputs/checkbox-group/overview.md new file mode 100644 index 000000000..2f3c3d8df --- /dev/null +++ b/docs/components/inputs/checkbox-group/overview.md @@ -0,0 +1,38 @@ +# Inputs >> Checkbox Group >> Overview ||10 + +`lion-checkbox-group` component enhances the functionality of the native `` element. +Its purpose is to provide a way for users to check **multiple** options amongst a set of choices, or to function as a single toggle. + +> You should use `` elements as the children of the ``. + +```js script +import { html } from '@lion/core'; +import '@lion/checkbox-group/define'; +``` + +```js story +export const main = () => html` + + + + + +`; +``` + +> Make sure that the checkbox-group also has a name attribute, this is necessary for the [lion-form](../form/overview.md)'s serialization result. + +## Features + +Since it extends from [lion-fieldset](../fieldset/overview.md), +it has all the features a fieldset has. + +## Installation + +```bash +npm i --save @lion/checkbox-group +``` + +```js +import '@lion/checkbox-group/define'; +``` diff --git a/docs/components/inputs/combobox/examples.md b/docs/components/inputs/combobox/examples.md new file mode 100644 index 000000000..85d119706 --- /dev/null +++ b/docs/components/inputs/combobox/examples.md @@ -0,0 +1,77 @@ +# Inputs >> Combobox >> Examples ||30 + +```js script +import { html } from '@lion/core'; +import './src/md-combobox/md-combobox.js'; +import './src/gh-combobox/gh-combobox.js'; +import './src/wa-combobox/wa-combobox.js'; +``` + +```js preview-story +export const MaterialDesign = () => html` + + Apple + Artichoke + Asparagus + Banana + Beets + +`; +``` + +```js preview-story +export const Github = () => html` + + master + develop + release + feat/abc + feat/xyz123 + +`; +``` + +```js preview-story +export const Whatsapp = () => html` + + + + + + + +`; +``` diff --git a/docs/components/inputs/combobox/features.md b/docs/components/inputs/combobox/features.md new file mode 100644 index 000000000..801d06bef --- /dev/null +++ b/docs/components/inputs/combobox/features.md @@ -0,0 +1,253 @@ +# Inputs >> Combobox >> Features ||20 + +A combobox is a widget made up of the combination of two distinct elements: + +- a single-line textbox +- an associated listbox overlay + +Based on the combobox configuration and entered textbox value, options in the listbox will be +filtered, checked, focused and the textbox value may be autocompleted. +Optionally the combobox contains a graphical button adjacent to the textbox, indicating the +availability of the popup. + +> Fore more information, consult [Combobox wai-aria design pattern](https://www.w3.org/TR/wai-aria-practices/#combobox) + +```js script +import { html } from '@lion/core'; +import { listboxData } from '../../../../packages/listbox/docs/listboxData.js'; +import '@lion/listbox/define'; +import '@lion/combobox/define'; +import './src/demo-selection-display.js'; +import { lazyRender } from './src/lazyRender.js'; +import levenshtein from './src/levenshtein.js'; +``` + +## Autocomplete + +Below you will find an overview of all possible `autocomplete` behaviors and how they correspond +to the configurable values `none`, `list`, `inline` and `both`. + +| | list | filter | focus | check | complete | +| -----: | :--: | :----: | :---: | :---: | :------: | +| none | ✓ | | | | | +| list | ✓ | ✓ | ✓ | ✓ | | +| inline | ✓ | | ✓ | ✓ | ✓ | +| both | ✓ | ✓ | ✓ | ✓ | ✓ | + +- **list** shows a list on keydown character press +- **filter** filters list of potential matches according to `matchmode` or provided `matchCondition` +- **focus** automatically focuses closest match (makes it the activedescendant) +- **check** automatically checks/selects closest match when `selection-follows-focus` is enabled (this is the default configuration) +- **complete** completes the textbox value inline (the 'missing characters' will be added as selected text) + +When `autocomplete="none"` is configured, the suggested options in the overlay are not filtered +based on the characters typed in the textbox. +Selection will happen manually by the user. + +```js preview-story +export const autocompleteNone = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +When `autocomplete="list"` is configured, it will filter listbox suggestions based on textbox value. + +```js preview-story +export const autocompleteList = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +When `autocomplete="inline"` is configured, it will present a value completion prediction inside the text input itself. +It does NOT filter list of potential matches. + +```js preview-story +export const autocompleteInline = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +When `autocomplete="both"` is configured, it combines the filtered list from `'list'` with the text input value completion prediction from `'inline'`. +This is the default value for `autocomplete`. + +```js preview-story +export const autocompleteBoth = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +## Match Mode + +When `match-mode="begin"` is applied, the entered text in the textbox only filters +options whose values begin with the entered text. For instance, the entered text 'ch' will match +with value 'Chard', but not with 'Artichoke'. +By default `match-mode="all"` is applied. This will also match parts of a word. +So 'ch' will both match 'Chard' and 'Artichoke'. + +```js preview-story +export const matchModeBegin = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +```js preview-story +export const matchModeAll = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +When the preconfigurable `match-mode` conditions are not sufficient, +one can define a custom matching function. +The example below matches when the Levenshtein distance is below 3 (including some other conditions). + +```js preview-story +export const customMatchCondition = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +## Options + +```js preview-story +export const showAllOnEmpty = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +### Changing defaults + +By default `selection-follows-focus` will be true (aligned with the +wai-aria examples and the native ``). +It is possible to disable this behavior, so the active/focused and checked/selected values +will be kept track of independently. + +> Note that, (just like in a listbox), selection-follows-focus will never be applicable for +> multiselect comboboxes. + +```js preview-story +export const noSelectionFollowsFocus = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +By default `rotate-keyboard-navigation` will be true (aligned with the +wai-aria examples and the natve ``). +It is possible to disable this behavior, see example below + +```js preview-story +export const noRotateKeyboardNavigation = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +## Multiple choice + +Add `multiple-choice` flag to allow multiple values to be selected. +This will: + +- keep the listbox overlay open on click of an option +- display a list of selected option representations next to the text box +- make the value of type `Array` instead of `String` + +> Please note that the lion-combobox-selection-display below is not exposed and only serves +> as an example. The selection part of a multiselect combobox is not yet accessible. Please keep +> in mind that for now, as a Subclasser, you would have to take care of this part yourself. + +```js preview-story +export const multipleChoice = () => html` + + + ${lazyRender( + listboxData.map( + (entry, i) => + html` ${entry} `, + ), + )} + +`; +``` + +## Invoker button + +```js preview-story +export const invokerButton = () => html` + + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +## Listbox compatibility + +All configurations that can be applied to `lion-listbox`, can be applied to `lion-combobox` as well. +See the [listbox documentation](../listbox/overview.md) for more information. diff --git a/docs/components/inputs/combobox/index.md b/docs/components/inputs/combobox/index.md new file mode 100644 index 000000000..be43f2d35 --- /dev/null +++ b/docs/components/inputs/combobox/index.md @@ -0,0 +1,3 @@ +# Inputs >> Combobox ||20 + +-> go to Overview diff --git a/docs/components/inputs/combobox/overview.md b/docs/components/inputs/combobox/overview.md new file mode 100644 index 000000000..47766ec3e --- /dev/null +++ b/docs/components/inputs/combobox/overview.md @@ -0,0 +1,47 @@ +# Inputs >> Combobox >> Overview ||10 + +A combobox is a widget made up of the combination of two distinct elements: + +- a single-line textbox +- an associated listbox overlay + +Based on the combobox configuration and entered textbox value, options in the listbox will be +filtered, checked, focused and the textbox value may be autocompleted. +Optionally, the combobox contains a graphical button adjacent to the textbox, indicating the +availability of the pop-up. + +> Fore more information, consult [Combobox wai-aria design pattern](https://www.w3.org/TR/wai-aria-practices/#combobox) + +```js script +import { html } from '@lion/core'; +import { listboxData } from '../../../../packages/listbox/docs/listboxData.js'; +import '@lion/listbox/define'; +import '@lion/combobox/define'; +import { lazyRender } from './src/lazyRender.js'; +``` + +```js preview-story +export const main = () => html` + + ${lazyRender( + listboxData.map(entry => html` ${entry} `), + )} + +`; +``` + +[...show more](./examples.md) + +## Features + +> tbd + +## Installation + +```bash +npm i --save @lion/combobox +``` + +```js +import '@lion/combobox/define'; +``` diff --git a/packages/combobox/docs/LinkMixin.js b/docs/components/inputs/combobox/src/LinkMixin.js similarity index 90% rename from packages/combobox/docs/LinkMixin.js rename to docs/components/inputs/combobox/src/LinkMixin.js index 2f87c7321..305abc5b5 100644 --- a/packages/combobox/docs/LinkMixin.js +++ b/docs/components/inputs/combobox/src/LinkMixin.js @@ -1,7 +1,7 @@ import { dedupeMixin } from '@lion/core'; /** - * @typedef {import('@lion/core').PropertyValues } changedProperties + * @typedef {import('lit-element').PropertyValues } changedProperties */ /** @@ -51,9 +51,6 @@ const LinkMixinImplementation = superclass => if (changedProperties.has('target')) { this._nativeAnchor.target = this.target; } - if (changedProperties.has('rel')) { - this._nativeAnchor.rel = this.rel; - } } __navigate() { diff --git a/packages/combobox/docs/demo-selection-display.js b/docs/components/inputs/combobox/src/demo-selection-display.js similarity index 97% rename from packages/combobox/docs/demo-selection-display.js rename to docs/components/inputs/combobox/src/demo-selection-display.js index b7e60b153..1ab2c09e8 100644 --- a/packages/combobox/docs/demo-selection-display.js +++ b/docs/components/inputs/combobox/src/demo-selection-display.js @@ -94,7 +94,7 @@ export class DemoSelectionDisplay extends LitElement { } /** - * @param {import('@lion/core').PropertyValues } changedProperties + * @param {import('lit-element').PropertyValues } changedProperties */ firstUpdated(changedProperties) { super.firstUpdated(changedProperties); @@ -106,7 +106,7 @@ export class DemoSelectionDisplay extends LitElement { } /** - * @param {import('@lion/core').PropertyValues } changedProperties + * @param {import('lit-element').PropertyValues } changedProperties */ onComboboxElementUpdated(changedProperties) { if (changedProperties.has('modelValue')) { diff --git a/packages/combobox/docs/gh-combobox/gh-button.js b/docs/components/inputs/combobox/src/gh-combobox/gh-button.js similarity index 96% rename from packages/combobox/docs/gh-combobox/gh-button.js rename to docs/components/inputs/combobox/src/gh-combobox/gh-button.js index e6512c164..c90190b61 100644 --- a/packages/combobox/docs/gh-combobox/gh-button.js +++ b/docs/components/inputs/combobox/src/gh-combobox/gh-button.js @@ -65,10 +65,5 @@ export class GhButton extends LionButton { `; } - - constructor() { - super(); - this.value = ''; - } } customElements.define('gh-button', GhButton); diff --git a/packages/combobox/docs/gh-combobox/gh-combobox.js b/docs/components/inputs/combobox/src/gh-combobox/gh-combobox.js similarity index 99% rename from packages/combobox/docs/gh-combobox/gh-combobox.js rename to docs/components/inputs/combobox/src/gh-combobox/gh-combobox.js index 8e6c6ce33..7c6880ca8 100644 --- a/packages/combobox/docs/gh-combobox/gh-combobox.js +++ b/docs/components/inputs/combobox/src/gh-combobox/gh-combobox.js @@ -2,7 +2,7 @@ import { css, html } from '@lion/core'; import { LionOption } from '@lion/listbox'; import { renderLitAsNode } from '@lion/helpers'; // import { withModalDialogConfig } from '@lion/overlays'; -import { LionCombobox } from '../../src/LionCombobox.js'; +import { LionCombobox } from '@lion/combobox'; import './gh-button.js'; export class GhOption extends LionOption { diff --git a/packages/combobox/docs/lazyRender.js b/docs/components/inputs/combobox/src/lazyRender.js similarity index 100% rename from packages/combobox/docs/lazyRender.js rename to docs/components/inputs/combobox/src/lazyRender.js diff --git a/packages/combobox/docs/levenshtein.js b/docs/components/inputs/combobox/src/levenshtein.js similarity index 100% rename from packages/combobox/docs/levenshtein.js rename to docs/components/inputs/combobox/src/levenshtein.js diff --git a/packages/combobox/docs/md-combobox/MdFieldMixin.js b/docs/components/inputs/combobox/src/md-combobox/MdFieldMixin.js similarity index 100% rename from packages/combobox/docs/md-combobox/MdFieldMixin.js rename to docs/components/inputs/combobox/src/md-combobox/MdFieldMixin.js diff --git a/packages/combobox/docs/md-combobox/md-combobox.js b/docs/components/inputs/combobox/src/md-combobox/md-combobox.js similarity index 97% rename from packages/combobox/docs/md-combobox/md-combobox.js rename to docs/components/inputs/combobox/src/md-combobox/md-combobox.js index 39469d6e4..db579b814 100644 --- a/packages/combobox/docs/md-combobox/md-combobox.js +++ b/docs/components/inputs/combobox/src/md-combobox/md-combobox.js @@ -1,6 +1,6 @@ import { css, html } from '@lion/core'; import { LionOption } from '@lion/listbox'; -import { LionCombobox } from '../../src/LionCombobox.js'; +import { LionCombobox } from '@lion/combobox'; import { MdFieldMixin } from './MdFieldMixin.js'; import './style/md-ripple.js'; import './style/load-roboto.js'; diff --git a/packages/combobox/docs/md-combobox/md-input.js b/docs/components/inputs/combobox/src/md-combobox/md-input.js similarity index 100% rename from packages/combobox/docs/md-combobox/md-input.js rename to docs/components/inputs/combobox/src/md-combobox/md-input.js diff --git a/packages/combobox/docs/md-combobox/style/load-roboto.js b/docs/components/inputs/combobox/src/md-combobox/style/load-roboto.js similarity index 100% rename from packages/combobox/docs/md-combobox/style/load-roboto.js rename to docs/components/inputs/combobox/src/md-combobox/style/load-roboto.js diff --git a/packages/combobox/docs/md-combobox/style/md-ripple.js b/docs/components/inputs/combobox/src/md-combobox/style/md-ripple.js similarity index 100% rename from packages/combobox/docs/md-combobox/style/md-ripple.js rename to docs/components/inputs/combobox/src/md-combobox/style/md-ripple.js diff --git a/packages/combobox/docs/wa-combobox/wa-combobox.js b/docs/components/inputs/combobox/src/wa-combobox/wa-combobox.js similarity index 84% rename from packages/combobox/docs/wa-combobox/wa-combobox.js rename to docs/components/inputs/combobox/src/wa-combobox/wa-combobox.js index 9d4162b0b..c786ba8a7 100644 --- a/packages/combobox/docs/wa-combobox/wa-combobox.js +++ b/docs/components/inputs/combobox/src/wa-combobox/wa-combobox.js @@ -1,7 +1,7 @@ import { html, css } from '@lion/core'; import { renderLitAsNode } from '@lion/helpers'; import { LionOption } from '@lion/listbox'; -import { LionCombobox } from '../../src/LionCombobox.js'; +import { LionCombobox } from '@lion/combobox'; class WaOption extends LionOption { static get properties() { @@ -167,9 +167,9 @@ class WaOption extends LionOption { :host([is-user-text-read]) .wa-option__content-row2-text-inner-icon { color: lightblue; } - .wa-selected { - color: #009688; - } + /* + .wa-option__content-row2-menu { + } */ `, ]; } @@ -178,7 +178,13 @@ class WaOption extends LionOption { return html`