Compare commits

...

1350 Commits

Author SHA1 Message Date
Cory LaViska
8ee519d40a fix positioning 2021-10-30 15:54:56 -04:00
Cory LaViska
6bc17d48c3 update examples 2021-10-29 18:35:24 -04:00
Cory LaViska
a1263f1b9d add experimental context menu 2021-10-29 18:32:45 -04:00
Cory LaViska
d69ebab765 update examples 2021-10-29 18:32:26 -04:00
Cory LaViska
0504946dac refactor popper creation 2021-10-29 18:32:12 -04:00
Cory LaViska
fbd6691711 improve search panel color 2021-10-29 14:42:17 -04:00
Cory LaViska
aec17da6b0 improve trigger border color in dark mode 2021-10-29 14:35:57 -04:00
Cory LaViska
639533662d update changelog 2021-10-26 09:35:59 -04:00
Cory LaViska
a340ce4a68 document part 2021-10-26 09:35:46 -04:00
Cory LaViska
6e5fe64e8b add eye dropper 2021-10-26 09:35:07 -04:00
Cory LaViska
84bdbb84b8 update lit 2021-10-26 09:34:48 -04:00
Cory LaViska
f91ffb6cb4 fix border radius on single button groups 2021-10-26 09:34:33 -04:00
Cory LaViska
13815199a3 fix dark theme link 2021-10-22 10:57:07 -04:00
Cory LaViska
98c20ff551 2.0.0-beta.58 2021-10-22 10:52:27 -04:00
Cory LaViska
479b6b9081 bundle back up for now 2021-10-22 10:51:17 -04:00
Cory LaViska
c640d2ea77 add stack overflow section 2021-10-19 10:51:41 -04:00
Cory LaViska
715547d2fd update changelog 2021-10-19 09:56:41 -04:00
Cory LaViska
8a914a536b fix cssproperty docs 2021-10-19 09:56:28 -04:00
Cory LaViska
f56b6c0648 remove RAFs 2021-10-19 09:52:41 -04:00
Denis Korablev
25aa8318d9 fix(sl-range): add value change handler (#572) 2021-10-19 09:48:39 -04:00
Cory LaViska
72f2cbe9e8 fix aspect ratio bug 2021-10-19 09:43:16 -04:00
Cory LaViska
fc7836084a add tooltip guard 2021-10-18 17:54:29 -04:00
Cory LaViska
60d9d9202b update bootstrap-icons to 1.6.1 2021-10-18 17:07:52 -04:00
Cory LaViska
a9df468282 fixes #563 2021-10-18 17:07:07 -04:00
Yuki Nishijima
0bba773c3e Bring the divider back to the Shadow DOM (#568) 2021-10-18 09:14:13 -04:00
Cory LaViska
7be03ae623 fix metadata plugin 2021-10-18 08:58:50 -04:00
Cory LaViska
d4741532f5 fix build dir 2021-10-16 10:35:42 -04:00
Cory LaViska
10f31efefa fix comment parser 2021-10-16 10:28:51 -04:00
Cory LaViska
be662ddf32 add animated-image 2021-10-16 08:29:25 -04:00
Cory LaViska
ff84beaade use :enabled 2021-10-14 09:02:00 -04:00
Cory LaViska
8dba8fa5fb fix tooltip bug 2021-10-14 09:01:37 -04:00
Cory LaViska
3a3f5552a7 fix test:watch 2021-10-14 08:39:17 -04:00
Cory LaViska
88cba353c0 add labels examples 2021-10-14 08:34:54 -04:00
Cory LaViska
a2851370bb revert styles 2021-10-14 08:32:11 -04:00
Cory LaViska
7c0ef7dcf0 Merge branch 'christoshrousis-test/progress' into next 2021-10-14 08:25:42 -04:00
Cory LaViska
fb6d5d89b8 use label attrib 2021-10-14 08:24:38 -04:00
Cory LaViska
45ceff4c08 Merge branch 'test/progress' of https://github.com/christoshrousis/shoelace into christoshrousis-test/progress 2021-10-14 08:10:57 -04:00
Cory LaViska
6169abc700 update bootstrap icons 2021-10-14 07:21:27 -04:00
Cory LaViska
c09e12d13e 2.0.0-beta.57 2021-10-13 17:34:04 -04:00
Cory LaViska
6152e15e10 fix esm links 2021-10-13 17:30:13 -04:00
Cory LaViska
79910b2ae8 2.0.0-beta.56 2021-10-13 17:14:22 -04:00
Cory LaViska
c347df7c17 rework build to support bare specifiers 2021-10-13 17:12:50 -04:00
Cory LaViska
e9e2b35c59 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-10-13 08:30:16 -04:00
Denis Korablev
8ae753c396 feat: add hoist attribute for sl-tooltip (#565) 2021-10-13 08:29:38 -04:00
Cory LaViska
d2c94321f2 update docs 2021-10-12 10:26:26 -04:00
Yuki Nishijima
4c10f8a537 Update the CSS path in the Integrating with Rails (#561) 2021-10-11 08:25:09 -04:00
Christos Hrousis
9a19cc2173 revert: misunderstood part/slot definition. 2021-10-10 13:37:32 +11:00
Christos Hrousis
c4cbc894f5 revert: misunderstood part/slot definition. 2021-10-10 13:36:41 +11:00
Christos Hrousis
449f5e6c7f style: typo. 2021-10-10 13:24:28 +11:00
Christos Hrousis
34447a3f2f test: migrate progress-ring tests to progress-bar
- Match coverage with progress-ring
- Attached titles/label/labelledby
- Value '' on aria-valuenow is does not pass AXE
2021-10-10 13:24:01 +11:00
Christos Hrousis
eee97d7dba test: cover progress-ring
- Add title to make ring accessibly hoverable.
- Add label/labelledby as aria options.
- Remove ununsed label slot.
2021-10-10 13:05:40 +11:00
Christos Hrousis
f16392947a docs: ring uses css prop for track-width. 2021-10-10 13:00:41 +11:00
Cory LaViska
c3adf92b49 2.0.0-beta.55 2021-10-08 17:06:12 -04:00
Cory LaViska
a6580b018d updat3e changelog 2021-10-08 17:05:53 -04:00
Cory LaViska
00c843c7ce revert unbundling 2021-10-08 17:04:30 -04:00
Cory LaViska
5fe55a4db9 2.0.0-beta.54 2021-10-08 16:55:09 -04:00
Cory LaViska
4ca998c346 revert 2021-10-08 16:54:57 -04:00
Cory LaViska
42b3e2cc11 update changelog 2021-10-08 16:53:31 -04:00
Cory LaViska
59fb8db6be unbundle select deps 2021-10-08 16:52:01 -04:00
Cory LaViska
664beafefa 2.0.0-beta.54 2021-10-08 16:42:53 -04:00
Cory LaViska
04443a64e2 update changelog 2021-10-08 16:39:10 -04:00
Cory LaViska
92dedf3386 ship bare module specifiers for prod 2021-10-08 10:11:12 -04:00
Cory LaViska
2ba5fb9820 update command line args 2021-10-08 10:10:26 -04:00
Cory LaViska
222235159b rename clear => remove 2021-10-07 09:52:23 -04:00
Cory LaViska
1061bd5e0d add disabled prop 2021-10-07 09:31:20 -04:00
Cory LaViska
ccec9a8348 fix initial disabled state 2021-10-07 09:30:47 -04:00
Cory LaViska
bf9e06e67d remove attr column 2021-10-05 10:41:52 -04:00
Cory LaViska
1e03d222c5 fix code in tables 2021-10-05 10:41:39 -04:00
Cory LaViska
3722f46b8e Merge branch 'kanoni4567-next' into next 2021-10-05 09:03:51 -04:00
Cory LaViska
8d7bf97127 Merge branch 'next' of https://github.com/kanoni4567/shoelace into kanoni4567-next 2021-10-05 09:01:35 -04:00
Cory LaViska
d26c1a6407 update docs 2021-10-05 08:58:41 -04:00
Rich Klein
f296ff8476 Create integrating-with-laravel.md (#553)
* Create integrating-with-laravel.md

Instructions for using Shoelace components in a Laravel 8.x application.

* Update integrating-with-laravel.md

Added a section for setting the base path and switched to using the full import path for each component. Also included a full `bootstrap.js` example.
2021-10-05 08:54:12 -04:00
Christos Hrousis
a75a71994a test: component/spinner (#556)
- covers accessibility
- provides explainer for aria-busy and aria-live tags.
2021-10-05 08:53:28 -04:00
Shanyu Cui
7d1373a1d1 radio: emit sl-change when toggled via arrow keys 2021-10-04 23:27:28 -07:00
Shanyu Cui
23abc50015 Merge branch 'shoelace-style:next' into next 2021-10-04 22:39:37 -07:00
Cory LaViska
5e28d1131a 2.0.0-beta.53 2021-10-04 09:31:07 -04:00
Cory LaViska
a141e64a69 update version 2021-10-04 09:30:21 -04:00
Cory LaViska
e12ee97bd9 add --padding to tab panel 2021-10-04 09:29:14 -04:00
Cory LaViska
ebd84642e1 Merge branch 'christoshrousis-test/card' into next 2021-10-04 09:06:55 -04:00
Christos Hrousis
888ac2ea0d test: first pass test.
- Cover use of header slot.
- Cover use of footer slot.
- Cover use of image slot.
2021-10-02 19:44:45 +10:00
Cory LaViska
37068c922c add margin 2021-10-01 09:03:29 -04:00
Cory LaViska
eec24d2ed1 add sl-mutation-observer 2021-09-30 18:32:59 -04:00
Cory LaViska
8fa9d629a3 fix tag default 2021-09-30 17:42:34 -04:00
Cory LaViska
ef22dd7dc4 fix docs 2021-09-30 17:16:27 -04:00
Cory LaViska
3f12624b78 bye, dotty! 2021-09-30 11:20:05 -04:00
Cory LaViska
d6fa67374c revert table change 2021-09-30 09:37:39 -04:00
Cory LaViska
d4183cf718 fix indentations 2021-09-30 09:28:00 -04:00
Cory LaViska
4ad0480039 rename percentage => value 2021-09-30 09:02:28 -04:00
Cory LaViska
7188425ac0 fix animation bug 2021-09-30 08:40:21 -04:00
Cory LaViska
c83581cf47 improve search 2021-09-30 08:07:15 -04:00
Cory LaViska
f8fa29f157 Merge branch 'timefordroids-550' into next 2021-09-30 07:51:54 -04:00
Cory LaViska
f2a4db6291 update docs, expose custom properties, rework to not use getComputedStyle 2021-09-30 07:51:28 -04:00
Denis
a4aff0b1e9 #550 added progress indicator to sl-range component 2021-09-30 11:20:39 +04:00
Cory LaViska
f5c2e0b425 fixes #549 2021-09-29 17:03:37 -04:00
Cory LaViska
2f88c55ec0 fix default height 2021-09-29 09:40:56 -04:00
Cory LaViska
db7075a91a update changelog 2021-09-29 08:42:39 -04:00
Narendra Sisodiya
8ac007ba9a Removed lit-html and added lit (#547) 2021-09-29 08:40:26 -04:00
Cory LaViska
111fa8397c fix default outline border 2021-09-29 08:38:43 -04:00
Cory LaViska
0ef4e92a96 add border 2021-09-29 08:35:43 -04:00
Cory LaViska
9123afac18 add examples 2021-09-29 08:33:52 -04:00
Cory LaViska
1b5dca52e3 add divider component 2021-09-29 08:03:03 -04:00
Christos Hrousis
bc3e9c43da test: components/breadcrumb-item (#541)
* test: migrate skipped tests to the breadcrumb-item

* test: when rendering a HTMLAnchorElement

* test: add checks for classes.

* test: uplift langauge and query selector to test label part

* test: default button test

* refactor: set default for rel on prop declaration.
2021-09-28 08:27:19 -04:00
Cory LaViska
ded01cfd8a fixes #544 2021-09-28 08:22:26 -04:00
Cory LaViska
c737b7494f fix comments 2021-09-27 17:58:14 -04:00
Cory LaViska
47aff56e71 add panel border width token 2021-09-27 16:53:24 -04:00
Cory LaViska
15ce341d81 add filled tokens and update styles 2021-09-27 10:48:47 -04:00
Cory LaViska
7476204258 add theme toggle shortcut 2021-09-27 10:24:51 -04:00
Cory LaViska
e083b1a02e revert luminance removal and rework surface tokens 2021-09-27 10:24:29 -04:00
Cory LaViska
fa74fc54e3 fix bg 2021-09-24 22:38:08 -04:00
Cory LaViska
fbbeec6d2f Merge branch 'christoshrousis-test/breadcrumb' into next 2021-09-24 22:31:21 -04:00
Cory LaViska
b4192364f6 Merge branch 'test/breadcrumb' of https://github.com/christoshrousis/shoelace into christoshrousis-test/breadcrumb 2021-09-24 22:30:16 -04:00
Cory LaViska
c7dc82947f add filled variant 2021-09-24 22:28:14 -04:00
Christos Hrousis
c38fd3986c test: uplift sepcificity of aria test, and test separator. 2021-09-25 12:12:50 +10:00
Christos Hrousis
35d7926e18 test: first pass test for breadcrumb 2021-09-25 11:41:00 +10:00
Christos Hrousis
86e06ce1e6 test: start the breadcrumb test. 2021-09-25 11:41:00 +10:00
Cory LaViska
1a08f063a6 add outline buttons; closes #522 2021-09-24 16:40:03 -04:00
Cory LaViska
740208ed76 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-09-24 09:18:45 -04:00
Cory LaViska
521f6fe3f1 update test 2021-09-24 09:18:28 -04:00
Cory LaViska
f43d490763 Create node.js.yml 2021-09-24 09:07:06 -04:00
Christos Hrousis
898179b645 test: components/avatar (#529)
* test: introduce first pass test for components/avatar
feat: set alt="" on img element

* test: resolve img src 404 errors

* test: remove bad test

* test: test children by assigning nodes...

* test: add patches similar to badge patch

* style: address typing issues.
2021-09-24 08:56:08 -04:00
Cory LaViska
8c3888da02 add control part to select 2021-09-24 08:48:01 -04:00
Cory LaViska
e1471ec9a1 change default dropdown distance 2021-09-24 08:31:54 -04:00
Cory LaViska
eac07a51ba update issue templates 2021-09-23 09:32:53 -04:00
Cory LaViska
753000b56a update changelog 2021-09-23 08:54:04 -04:00
Cory LaViska
8ab2907c3f update components to use surface tokens 2021-09-23 08:53:05 -04:00
Cory LaViska
723ee80c8f update docs to use surface tokens 2021-09-23 08:52:49 -04:00
Cory LaViska
e1c003c8df add surface tokens and remove luminance shift 2021-09-23 08:52:18 -04:00
Cory LaViska
96c82dc69f fix discord badge 2021-09-23 07:54:14 -04:00
Cory LaViska
0dd9483797 remove bogus space 2021-09-22 15:35:26 -04:00
Cory LaViska
4da110087d update badges 2021-09-22 10:04:42 -04:00
Cory LaViska
7f75a64647 update vue usage 2021-09-22 09:06:13 -04:00
Cory LaViska
71d7f6fd98 2.0.0-beta.52 2021-09-20 23:22:29 -04:00
Cory LaViska
42595f241f fix test 2021-09-20 23:20:29 -04:00
Cory LaViska
c67c84dfda simplify math 2021-09-20 23:14:39 -04:00
Cory LaViska
2ba6a3b097 remove unused style 2021-09-20 22:33:17 -04:00
Cory LaViska
0456ad96fb update changelog 2021-09-20 22:09:14 -04:00
Cory LaViska
0ab87b03fa remove dashes from animation descriptions 2021-09-20 22:05:27 -04:00
Cory LaViska
54fc41e175 update to lit 2.0 2021-09-20 22:01:21 -04:00
Cory LaViska
261e824290 update changelog 2021-09-20 11:07:51 -04:00
Cory LaViska
802363e1da Merge branch 'christoshrousis-test/badge' into next 2021-09-20 11:06:09 -04:00
Cory LaViska
1054d5bb74 Merge branch 'test/badge' of https://github.com/christoshrousis/shoelace into christoshrousis-test/badge 2021-09-20 11:04:49 -04:00
Cory LaViska
f5d143710e fixes #528 2021-09-20 10:41:10 -04:00
Christos Hrousis
c025208bf5 test: first pass for badge test 2021-09-20 18:11:00 +10:00
Cory LaViska
7306e39f3e Add no-codepen for previews with assets 2021-09-19 12:01:04 -04:00
Cory LaViska
0d30d183df fix typo 2021-09-19 11:43:16 -04:00
Cory LaViska
cd504a4127 fix color 2021-09-19 11:42:33 -04:00
Cory LaViska
bba41402aa update progress ring to use CSS 2021-09-17 18:15:13 -04:00
Cory LaViska
e1f129abc5 improve spinner animation and API 2021-09-17 17:48:44 -04:00
Cory LaViska
7e6c6924f2 make search a bit fuzzier 2021-09-17 16:27:11 -04:00
Cory LaViska
185fc4c942 add file name to search index 2021-09-17 16:26:57 -04:00
Cory LaViska
5f7c6b307f improve search height 2021-09-17 16:13:29 -04:00
Cory LaViska
a9f80467c3 remove gap 2021-09-17 16:09:32 -04:00
Jake Patterson
89fb1a8804 fix broken link design token (#526) 2021-09-15 09:22:38 -04:00
Cory LaViska
54bfce0d5d add link 2021-09-13 08:12:51 -04:00
Cory LaViska
dca1d1b413 update docs 2021-09-13 07:54:05 -04:00
Cory LaViska
4b07ee40a7 fixes #523 2021-09-12 19:57:48 -04:00
Cory LaViska
d8644c940b add links to description 2021-09-11 09:44:47 -04:00
Cory LaViska
7df70abb48 no longer true 2021-09-09 10:41:23 -04:00
Cory LaViska
6e3c5c0388 reduce member boost 2021-09-09 10:17:55 -04:00
Cory LaViska
6cbe2e288b fix home button in search 2021-09-09 09:23:45 -04:00
Cory LaViska
1f95c6ca6e 2.0.0-beta.51 2021-09-09 09:14:51 -04:00
Cory LaViska
ac6ae43449 add metadata to search index 2021-09-09 09:13:55 -04:00
Cory LaViska
ba3117f435 fix comment 2021-09-09 09:13:29 -04:00
Cory LaViska
fd449f68d9 update changelog 2021-09-09 08:49:12 -04:00
Cory LaViska
574947656c add importing section to docs 2021-09-09 08:46:37 -04:00
Cory LaViska
5b1b704d1d more mobile tweaks 2021-09-09 07:46:04 -04:00
Cory LaViska
abbdb207e0 fix mobile styles 2021-09-09 07:43:17 -04:00
Cory LaViska
2d89fc945f remove elevation 2021-09-08 17:04:12 -04:00
Cory LaViska
25b130ce2c not too fuzzy 2021-09-08 12:25:02 -04:00
Cory LaViska
ca098eb171 fuzzy search and icon 2021-09-08 12:05:28 -04:00
Cory LaViska
f6ccd119e8 fix styles 2021-09-08 10:01:54 -04:00
Cory LaViska
7b1f99b41a update t-shirt tokens 2021-09-08 09:51:31 -04:00
Cory LaViska
4193ee1980 use focus-visible for code block buttons 2021-09-08 07:37:22 -04:00
Cory LaViska
c718012c3e remove unused code 2021-09-08 07:37:07 -04:00
Cory LaViska
aca5c8af73 updates 2021-09-08 07:25:07 -04:00
Cory LaViska
2d4a699790 no backslashes 2021-09-08 07:18:23 -04:00
Cory LaViska
fc0475b2c5 adjust for mobile 2021-09-08 07:16:05 -04:00
Cory LaViska
0f6e13b8c9 update changelog 2021-09-07 16:32:21 -04:00
Cory LaViska
c60cfae677 search styles 2021-09-07 15:05:57 -04:00
Cory LaViska
ded05cf079 improve search 2021-09-07 14:44:46 -04:00
Cory LaViska
c360d471cd fix ios 2021-09-07 13:21:22 -04:00
Cory LaViska
382a39e6ed fix build loop 2021-09-07 13:13:18 -04:00
Cory LaViska
bfa1499889 less noise 2021-09-07 13:13:02 -04:00
Cory LaViska
053a5e9bd7 generate at build time 2021-09-07 11:53:32 -04:00
Cory LaViska
3677f6cf0f add dep 2021-09-07 11:53:19 -04:00
Cory LaViska
03fb75f030 custom search 2021-09-07 11:52:58 -04:00
Cory LaViska
8e209d2767 update docs 2021-09-07 08:03:59 -04:00
Cory LaViska
0cf77a4115 update docs 2021-09-06 19:45:48 -04:00
Cory LaViska
14368c4ce2 Fix comment 2021-09-06 19:22:02 -04:00
Cory LaViska
e74838fdc1 adjust default button elevation 2021-09-03 10:06:09 -04:00
Cory LaViska
3f64b13d70 add missing tokens 2021-09-03 08:35:29 -04:00
Cory LaViska
613f4b6440 remove icon dep; improve copy animation 2021-09-03 08:21:16 -04:00
Cory LaViska
1bfa4c6ba8 reduce size 2021-09-03 08:09:07 -04:00
Cory LaViska
9089473cf0 improve elevation + overlay tokens 2021-09-03 08:03:32 -04:00
Cory LaViska
687eb7d0dc fix buttons on mobile 2021-09-02 10:57:59 -04:00
Cory LaViska
52cb8adf65 2.0.0-beta.50 2021-09-01 09:10:42 -04:00
Cory LaViska
06f241adb1 update version 2021-09-01 09:10:22 -04:00
Cory LaViska
f5ba173156 add breadcrumb + breadcrumb item 2021-09-01 09:06:19 -04:00
Cory LaViska
5bd7bfb4ce fix buttons on mobile 2021-08-31 07:41:53 -04:00
Cory LaViska
e4413dceee update docs 2021-08-31 07:37:41 -04:00
Cory LaViska
f644454080 add new typography tokens 2021-08-30 16:39:08 -04:00
Cory LaViska
16f4b485b5 fix tables 2021-08-30 16:38:53 -04:00
Cory LaViska
679dd4578c add click transition 2021-08-30 16:21:02 -04:00
Cory LaViska
00bf318ee9 prevent errors when setting controls undefined 2021-08-30 08:27:47 -04:00
Sidharth Ramesh
da3415d029 Prevents error if sl-input has value undefined (#513)
The sl-input's value state being `undefined` is very common when using shoelace with frameworks. Instead of erroring out and not showing the input, this should handle it gracefully.
2021-08-30 08:25:25 -04:00
Benny Powers
147a8d2f57 docs: add themed css to getting started snippet (#512)
* docs: add themed css to getting started snippet

* docs: add instructions to force light or dark themes
2021-08-27 17:05:31 -04:00
Cory LaViska
a1d354ac15 remove unused import 2021-08-27 16:45:33 -04:00
Cory LaViska
1fb0e41603 2.0.0-beta.49 2021-08-27 16:44:35 -04:00
Cory LaViska
f121c119f0 update changelog 2021-08-27 16:44:01 -04:00
Cory LaViska
f4c472e7de remove --focus-ring 2021-08-27 09:07:42 -04:00
Cory LaViska
719d62b670 fix spacing in select clearable 2021-08-27 09:03:10 -04:00
Cory LaViska
165306f56a remove no-fieldset; add fieldset 2021-08-27 09:00:01 -04:00
Cory LaViska
248bb32977 fix radio focus visible styles 2021-08-27 08:54:00 -04:00
Cory LaViska
dfb9127052 fix checkbox/switch focus visible 2021-08-27 08:50:31 -04:00
Cory LaViska
5933e948e1 fix checkbox focus visible 2021-08-27 08:38:11 -04:00
Cory LaViska
624f6ef5a1 fix arrow keys 2021-08-27 08:26:48 -04:00
Cory LaViska
2865b546fa add --sl-focus-ring and update styles 2021-08-27 08:21:18 -04:00
Cory LaViska
9d7c3b2af9 no need to force focus 2021-08-27 08:20:26 -04:00
Cory LaViska
033896dfc2 adjust default button 2021-08-27 08:20:07 -04:00
Cory LaViska
10d95ba8e6 remove focus from resizer 2021-08-26 10:18:54 -04:00
Cory LaViska
43f74583ea rework focus-visible logic 2021-08-26 08:35:36 -04:00
Cory LaViska
36d499f253 use a pill button 2021-08-26 07:45:30 -04:00
Cory LaViska
4c6e61e6dd improve switch contrast 2021-08-25 17:57:52 -04:00
Cory LaViska
0829af77c0 fix --sl-color-neutral-0|1000 2021-08-25 17:48:37 -04:00
Cory LaViska
f3281d3985 fix toggle hover 2021-08-25 17:36:46 -04:00
Cory LaViska
5cd5567292 disable ghost mode 2021-08-24 09:03:01 -04:00
Cory LaViska
c0102a1658 fix dev dep 2021-08-24 08:57:02 -04:00
Cory LaViska
c173d0d76e don't use hash routing in dev 2021-08-24 08:49:27 -04:00
Cory LaViska
d7dd4b82da add missing component 2021-08-24 08:14:28 -04:00
Cory LaViska
f9010cf3ca add date to input 2021-08-24 08:13:36 -04:00
Cory LaViska
a0d2dbf685 update lit and lit-html 2021-08-23 09:17:21 -04:00
Cory LaViska
d679d27043 update changelog 2021-08-23 09:12:50 -04:00
Cory LaViska
9c0641dcad fixes #508 2021-08-23 09:11:40 -04:00
Cory LaViska
af852a088c improve icon color contrast 2021-08-23 09:11:27 -04:00
Cory LaViska
76f04c0b0e link to color token generator 2021-08-23 09:06:20 -04:00
Cory LaViska
27376df5f2 improve color picker 2021-08-23 08:50:18 -04:00
Cory LaViska
fd285dbd6f use black for overlay color 2021-08-23 08:17:45 -04:00
Cory LaViska
76e1d4b403 adjust elevation tokens 2021-08-20 17:23:59 -04:00
Cory LaViska
51dbc1a1ee remove elevation when inline 2021-08-20 17:00:07 -04:00
Cory LaViska
7095236116 fix whitespace 2021-08-20 14:19:19 -04:00
Cory LaViska
6014c888c2 2.0.0-beta.48 2021-08-20 09:59:57 -04:00
Cory LaViska
c41714c6f3 fix menu selection via type to select 2021-08-20 09:55:32 -04:00
Cory LaViska
a3626e121b update changelog 2021-08-20 09:55:14 -04:00
Cory LaViska
b7caba8b11 Merge branch 'gtyamamoto-fix/ctrlkeys-usability-sl-select' into next 2021-08-20 09:40:43 -04:00
Cory LaViska
0a45f446e2 Merge branch 'fix/ctrlkeys-usability-sl-select' of https://github.com/gtyamamoto/shoelace into gtyamamoto-fix/ctrlkeys-usability-sl-select 2021-08-20 09:38:57 -04:00
Cory LaViska
917dbb12da update changelog 2021-08-20 09:36:43 -04:00
gtyamamoto
767c0b3675 fix: allow ctrl/command + key when the sl-select is on focus
- doing a more simplistic approach to handle ctrlKey/metaKey values
2021-08-20 09:20:01 -03:00
Cory LaViska
30477bb0ad shifted dark theme 2021-08-20 07:56:18 -04:00
Cory LaViska
1ce4d31503 update screen color 2021-08-19 17:29:12 -04:00
gtyamamoto
066f7cfa08 fix: allow ctrl/command + key when the sl-select is on focus 2021-08-19 17:21:18 -03:00
Cory LaViska
be8f2bf280 improve help text contrast 2021-08-19 15:01:48 -04:00
Cory LaViska
e339571ce0 fix menu bug 2021-08-19 09:34:08 -04:00
Cory LaViska
3ea89b3956 fix mouseup 2021-08-19 09:04:08 -04:00
Cory LaViska
1e65d45844 add design token section 2021-08-19 08:36:12 -04:00
Cory LaViska
99750b8edb improve table viewing on mobile (still not great) 2021-08-19 08:28:52 -04:00
Cory LaViska
2af3831366 fix example 2021-08-19 08:01:54 -04:00
Cory LaViska
5d9c65041e info => neutral 2021-08-19 08:01:45 -04:00
Cory LaViska
e789f92db2 remove outdated warning 2021-08-19 07:58:56 -04:00
Cory LaViska
9a1f7dd3eb fix SVG in safari 2021-08-19 07:57:39 -04:00
Cory LaViska
fb48c4cf0e remove ref attr 2021-08-18 18:17:58 -04:00
Cory LaViska
8c5dee529b revert SL brand color 2021-08-18 18:15:24 -04:00
Cory LaViska
c885b76bbc add theme color back 2021-08-18 17:56:51 -04:00
Cory LaViska
6d03f12e54 improve contrast; fixes #128 2021-08-18 17:54:35 -04:00
Cory LaViska
be5bbe95b6 change default effect to 'none' 2021-08-18 17:30:51 -04:00
Cory LaViska
e571c884c1 fix example 2021-08-18 17:29:59 -04:00
Cory LaViska
96008539d5 fix whitespace 2021-08-18 09:53:51 -04:00
Cory LaViska
8c221f33a8 docs styles 2021-08-18 09:52:51 -04:00
Cory LaViska
9612af06a8 update example 2021-08-18 08:55:59 -04:00
Cory LaViska
17c1be6dd7 pure inversion 2021-08-17 17:42:52 -04:00
Cory LaViska
6607cdb0bd remove extra comment 2021-08-17 17:04:57 -04:00
Cory LaViska
5f33bd312e fix theme picker again 2021-08-17 09:14:38 -04:00
Cory LaViska
185bc30893 improve theme picker 2021-08-16 17:58:34 -04:00
Cory LaViska
b35d5e9914 update examples and changelog 2021-08-16 17:05:28 -04:00
Cory LaViska
a89eab43c4 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-08-16 16:31:02 -04:00
Rafael Rossini
5eac4ebee8 Add prefix and suffix slot to sl-select component (#501)
* Add prefix and suffix slot to sl-select component

* Adding align-items: center in prefix/suffix and changing documentation to showcase using as visual aids
2021-08-16 16:30:55 -04:00
Cory LaViska
65a3c3a33c remove z-index 2021-08-16 16:17:55 -04:00
Cory LaViska
b0cf35d264 fix copy button animation 2021-08-12 12:57:13 -04:00
Cory LaViska
f8aff7dcd9 improve theme picker 2021-08-12 09:36:48 -04:00
Cory LaViska
b754912990 remove toggle transition 2021-08-12 09:00:06 -04:00
Cory LaViska
83a01cf0e2 update brand color 2021-08-12 08:59:56 -04:00
Cory LaViska
d81db3fd4b remove unused style 2021-08-12 08:39:06 -04:00
Cory LaViska
1b383888b8 remove unused z-index 2021-08-11 17:50:28 -04:00
Cory LaViska
cd76672831 use prefers-color-scheme by default 2021-08-11 17:50:17 -04:00
Cory LaViska
94f4d652b4 remove focus ring color tokens 2021-08-10 17:53:15 -04:00
Cory LaViska
5aab7c34e6 fix radio group focus bug 2021-08-10 17:24:52 -04:00
Cory LaViska
72eff3754f emit on left/right 2021-08-10 17:13:21 -04:00
Cory LaViska
0d3d9c8233 Merge branch 'bennypowers-fix/checkbox-emit-on-user-action-only' into next 2021-08-10 17:11:32 -04:00
Cory LaViska
3bb8614143 use fixture types consistently 2021-08-10 17:11:07 -04:00
Cory LaViska
2b12a47915 merge changes 2021-08-10 17:10:50 -04:00
Benny Powers
9216e72a3e fix: emit sl-change from radio and switch on user interaction only 2021-08-10 18:53:15 +03:00
Benny Powers
9b99a92dc1 fix: emit sl-change from checkbox on user interaction only
fixes #497
2021-08-10 18:53:15 +03:00
Cory LaViska
ab1a68d0f8 fix color 2021-08-10 11:40:59 -04:00
Cory LaViska
4fedf9548f faster copy animation 2021-08-10 11:16:44 -04:00
Cory LaViska
a396c86e84 improve code block button styles 2021-08-10 11:07:17 -04:00
Cory LaViska
75f2da3547 prettier 2021-08-10 10:57:24 -04:00
Cory LaViska
6c9a25a0c7 Merge branch 'theming' into next 2021-08-10 10:56:27 -04:00
Benny Powers
34db96822b Add href etc to sl-icon-button (#496)
* perf: only calculate the used button template

* feat: add href and friends to icon-button

closes #495
2021-08-10 10:52:17 -04:00
Cory LaViska
37e60c9dfe update changelog 2021-08-10 10:46:44 -04:00
Cory LaViska
54b2cbc608 inline script + style for codepen 2021-08-10 10:45:33 -04:00
Cory LaViska
7f4169e4e3 tweak styles 2021-08-10 10:45:18 -04:00
Cory LaViska
c356ec40d6 update theme docs 2021-08-10 09:08:50 -04:00
Cory LaViska
23a7268e84 square hover 2021-08-10 09:08:39 -04:00
Cory LaViska
35d960c09f better copy button styles 2021-08-10 09:01:53 -04:00
Cory LaViska
a7d81993d5 add codepen button to code blocks 2021-08-10 08:39:19 -04:00
Cory LaViska
e5af3257c9 add icons back 2021-08-09 09:21:55 -04:00
Cory LaViska
da83581f45 disallow expressions 2021-08-09 08:33:50 -04:00
Cory LaViska
5900594562 exit on startup when scripts fail 2021-08-09 08:33:30 -04:00
Cory LaViska
a050832da0 rename base.css to light.css 2021-08-09 08:06:59 -04:00
Guillaume Laforge
fe766dc438 Minor typo in the page describing forms (#492) 2021-08-06 19:36:55 -04:00
Cory LaViska
c1a5ce4b27 improve copy styles 2021-08-06 16:11:14 -04:00
Cory LaViska
64b0e63945 update theme docs 2021-08-06 15:52:48 -04:00
Cory LaViska
95f6841a48 update base theme class 2021-08-06 15:52:27 -04:00
Cory LaViska
3189c6fe98 change -0 -1000 to --sl-color-neutral-0|1000 2021-08-06 09:37:16 -04:00
Cory LaViska
9dbee4c686 add neutral color palette 2021-08-06 08:32:46 -04:00
Cory LaViska
04a2d45334 update content 2021-08-05 18:07:53 -04:00
Cory LaViska
6766af0f9d fix focus ring styles 2021-08-05 17:59:58 -04:00
Cory LaViska
c7058e7613 improve link contrast in docs 2021-08-05 17:48:04 -04:00
Cory LaViska
3d1f858301 black/white => empty/full 2021-08-05 17:42:12 -04:00
Cory LaViska
21de0db790 use color scale 2021-08-05 17:17:44 -04:00
Cory LaViska
c5d4c532b3 generate css files from themes/*.styles.ts 2021-08-05 16:48:15 -04:00
Cory LaViska
3877e89277 reword 2021-08-05 09:49:25 -04:00
Cory LaViska
688ac96faa colors 1000 => 950 2021-08-05 09:43:03 -04:00
Cory LaViska
e53f36e5ef update docs and changelog 2021-08-05 09:39:58 -04:00
Cory LaViska
ad35df2a17 use rgb primitives for color tokens to support alpha 2021-08-05 08:27:58 -04:00
Cory LaViska
fd104ad74f expose styles for js 2021-08-04 18:03:24 -04:00
Cory LaViska
bffa9a2ed8 improve palette styles 2021-08-04 17:54:18 -04:00
Cory LaViska
dfd18776c6 add :host selector 2021-08-04 08:14:47 -04:00
Cory LaViska
f746ef7954 update changelog 2021-08-03 17:51:53 -04:00
Cory LaViska
a71b83b4c3 update changelog 2021-08-03 17:46:19 -04:00
Cory LaViska
cebd206bcc rework design tokens and use inverted dark theme 2021-08-03 17:35:37 -04:00
Cory LaViska
d07311cf64 split utility styles out 2021-08-03 17:35:13 -04:00
Cory LaViska
7d6390d9bf adjust styles and use tokens when possible 2021-08-03 17:34:51 -04:00
Cory LaViska
68f40ed779 use token for track color 2021-08-03 17:23:17 -04:00
Cory LaViska
4d56124274 update installation instructions 2021-08-03 17:22:55 -04:00
Cory LaViska
6aa31e612a more contrast for avatars 2021-08-03 07:37:17 -04:00
Cory LaViska
6d9018627e fix transparent bg styles 2021-08-03 07:36:56 -04:00
Cory LaViska
28b0e74e04 semibold labels 2021-08-03 07:35:55 -04:00
Cory LaViska
246f1155e6 move qr out of utils 2021-08-03 07:31:00 -04:00
Cory LaViska
a59d29e10c update changelog 2021-07-28 09:04:06 -04:00
David Gonzalez
b13e2c32ff Simplify switch thumb calc (#490) 2021-07-28 09:03:22 -04:00
Cory LaViska
807cba18d1 fix type to select bug 2021-07-26 08:23:46 -04:00
Cory LaViska
e938f94ffc add console error 2021-07-26 08:20:18 -04:00
Cory LaViska
d6e6f2cb25 update doc 2021-07-23 16:27:56 -04:00
Cory LaViska
43328b94b7 2.0.0-beta.47 2021-07-18 16:22:07 -04:00
Cory LaViska
dde15b0881 update version 2021-07-18 16:15:46 -04:00
Andreas
d84fd95f3c Automate GitHub release creation (#483)
* automate github release creation

Adds a workflow file to create a GitHub release, when a version tag is pushed.

* set fix latest version of auto release action
2021-07-18 16:13:23 -04:00
Cory LaViska
efed99b890 Remove unused import in example 2021-07-18 16:10:25 -04:00
Cory LaViska
1a6c1ed1c3 fixes #480 2021-07-16 10:16:02 -04:00
Cory LaViska
fa82d31000 update changelog 2021-07-16 08:38:59 -04:00
Cory LaViska
d11e7fe562 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-07-16 08:29:45 -04:00
Shanyu Cui
e36a49b635 update hasSlot selector to search top-level only (#481) 2021-07-16 08:28:47 -04:00
Shanyu Cui
17df0e3cd3 Merge branch 'next' of github.com:shoelace-style/shoelace into next 2021-07-16 02:04:07 -07:00
Shanyu Cui
76df2fd204 update hasSlot selector to search top-level only 2021-07-16 02:03:02 -07:00
Cory LaViska
f9491bb944 simplify component gathering 2021-07-13 16:43:18 -04:00
Cory LaViska
3541540d84 fix grid handle drag behavior 2021-07-13 07:55:49 -04:00
Cory LaViska
1ae5b9cfcd add descr 2021-07-13 07:15:03 -04:00
Cory LaViska
e493bda6df fix changelog 2021-07-13 07:14:33 -04:00
Cory LaViska
7de15e94b2 adjust comment 2021-07-13 07:13:04 -04:00
Cory LaViska
002f847165 remove unused rule 2021-07-13 07:12:55 -04:00
Cory LaViska
a654f50c33 fix box-sizing 2021-07-13 07:12:24 -04:00
Cory LaViska
a2594d4a6b add note about deps 2021-07-12 11:40:25 -04:00
Cory LaViska
b98e1f6b20 fix radio group tabbing 2021-07-12 10:48:38 -04:00
Cory LaViska
a48eef2575 refactor base path logic 2021-07-12 10:36:29 -04:00
Cory LaViska
4aeb804441 auto import dependencies 2021-07-12 10:36:06 -04:00
Cory LaViska
a30adac959 add reflects column 2021-07-12 09:38:06 -04:00
Cory LaViska
d605de4e07 update analyzer 2021-07-12 09:37:55 -04:00
Cory LaViska
fe49ee0aad 2.0.0-beta.46 2021-07-09 20:55:37 -04:00
Cory LaViska
e47fd3b879 update version 2021-07-09 20:55:17 -04:00
Cory LaViska
383e039297 sass => lit styles 2021-07-09 20:45:44 -04:00
Cory LaViska
46a206de64 add interactive demo 2021-07-09 20:38:55 -04:00
Cory LaViska
f39cb976aa don't use "prop" 2021-07-08 17:41:10 -04:00
Cory LaViska
ad7c02f745 update analyzer 2021-07-08 17:25:05 -04:00
Cory LaViska
1c98a831d8 use roving tab index for menu 2021-07-08 17:23:47 -04:00
Cory LaViska
ffcdf4462b fixes #477 2021-07-07 08:30:31 -04:00
Cory LaViska
22cfc82d35 remove unnecessary bindings 2021-07-07 08:13:27 -04:00
Cory LaViska
83fbe9eccc remove unnecessary bindings 2021-07-07 08:13:07 -04:00
Cory LaViska
9a89c14e20 improve tabbable logic 2021-07-07 07:59:06 -04:00
Cory LaViska
6b1d762245 rename columns 2021-07-06 17:56:29 -04:00
Cory LaViska
0b9da0b049 fix comment 2021-07-06 17:56:19 -04:00
Cory LaViska
5bcce80b50 improve metadata parsing for new analyzer version 2021-07-06 10:29:58 -04:00
Cory LaViska
9f3bf24d06 show dev/next 2021-07-06 08:39:40 -04:00
Cory LaViska
647ab0ab78 fix jsdoc plugin 2021-07-06 08:39:29 -04:00
Cory LaViska
188a7b661e update changelog 2021-07-06 08:27:12 -04:00
Cory LaViska
fe4393593a Update analyzer 2021-07-06 08:26:20 -04:00
Cory LaViska
6fd5a97fde fix boolean true prop 2021-07-01 17:23:16 -04:00
Cory LaViska
10cd4b8999 cleanup unused things 2021-07-01 17:14:25 -04:00
Cory LaViska
cb3d76889d improve sl-animation 2021-07-01 09:34:00 -04:00
Cory LaViska
07504dd149 add meta tag for CEM 2021-07-01 07:15:53 -04:00
Cory LaViska
2ea5b65cb8 remove redundant types 2021-06-30 20:04:46 -04:00
Cory LaViska
f124c8d81b clarify comments 2021-06-30 20:03:34 -04:00
Cory LaViska
1e7567fb8f update analyzer 2021-06-30 20:03:17 -04:00
Cory LaViska
5f6874edbf remove options 2021-06-30 20:03:07 -04:00
Cory LaViska
3558bd5d9b update analyzer and remove dash plugin 2021-06-29 09:37:19 -04:00
Cory LaViska
8e45f7d785 2.0.0-beta.45 2021-06-29 08:48:07 -04:00
Cory LaViska
ceb234f0d5 update changelog 2021-06-29 08:47:29 -04:00
Cory LaViska
1c8a3ea7d2 fixes #466 2021-06-29 08:34:40 -04:00
Cory LaViska
522d6a5fc4 improve order 2021-06-29 07:08:49 -04:00
Cory LaViska
21a7df9a84 update analyzer 2021-06-28 16:50:28 -04:00
Cory LaViska
d6eeacbdc1 fix focus trap when open on init 2021-06-28 16:49:56 -04:00
Cory LaViska
d4d581e4fb fix metadata fetch bug 2021-06-28 09:43:55 -04:00
Cory LaViska
9c31d148fe fix argument 2021-06-28 09:31:22 -04:00
Cory LaViska
47c932bd46 fix incorrect types 2021-06-28 09:26:55 -04:00
Cory LaViska
cc7ab8f7c4 fix bad type 2021-06-28 09:25:47 -04:00
Cory LaViska
6883851866 don't use inferred types for analyzer 2021-06-28 09:23:39 -04:00
Cory LaViska
94a5c6244e update helper functions 2021-06-28 08:53:31 -04:00
Cory LaViska
42fb6c7100 update changelog 2021-06-28 08:36:57 -04:00
Cory LaViska
5e7fcdd105 refactor metadata fetching 2021-06-28 08:34:37 -04:00
Cory LaViska
12b0365ce0 hide private methods 2021-06-25 20:07:22 -04:00
Cory LaViska
114dfa3904 fix class name 2021-06-25 20:01:53 -04:00
Cory LaViska
e31a05beb0 Merge branch 'next' into metadata 2021-06-25 19:40:12 -04:00
Cory LaViska
a28942f264 use @watch and reorder handlers 2021-06-25 19:22:05 -04:00
Cory LaViska
af61f45ecb fixes #473 2021-06-25 19:02:34 -04:00
Cory LaViska
0da9955403 Add dashes back to metadata 2021-06-25 16:25:46 -04:00
Cory LaViska
e4f699641a remove script 2021-06-25 10:00:39 -04:00
Cory LaViska
23b56b4053 show default slot better 2021-06-25 09:59:36 -04:00
Cory LaViska
0971153a74 update analyzer 2021-06-25 09:58:41 -04:00
Cory LaViska
0b3abfae28 fix animations and support dash separators in descriptions 2021-06-25 09:58:26 -04:00
Cory LaViska
d0b9488c1c switch to custom elements manifest analyzer 2021-06-24 18:24:54 -04:00
Cory LaViska
698962e0ea fix tests 2021-06-23 09:14:58 -04:00
Cory LaViska
1c010ffe5a add sl-request-close event 2021-06-21 09:40:11 -04:00
Cory LaViska
95ba1b5849 update docs 2021-06-21 08:52:55 -04:00
Cory LaViska
19dba93cca use plop for npm run create 2021-06-18 10:07:17 -04:00
Cory LaViska
94fe4f1f46 remove { waitUntilFirstUpdate } when not needed 2021-06-18 08:51:00 -04:00
Cory LaViska
de9d43f67a fixes #468 2021-06-18 08:36:24 -04:00
Cory LaViska
301c58d6fb add initial tests 2021-06-18 08:34:42 -04:00
Cory LaViska
227ecc0193 2.0.0-beta.44 2021-06-17 17:40:01 -04:00
Cory LaViska
ee260e671f update version 2021-06-17 17:39:16 -04:00
Cory LaViska
1a954c5b25 convert build scripts to ESM 2021-06-17 17:38:48 -04:00
Cory LaViska
a14dd95c21 assign certain props as properties 2021-06-17 16:45:49 -04:00
Cory LaViska
19f7918435 remove comments 2021-06-17 16:44:53 -04:00
Cory LaViska
1e4de5f821 fixes #455 2021-06-16 08:42:02 -04:00
Cory LaViska
45f4b33eb1 add select sl-change test 2021-06-15 09:36:45 -04:00
Cory LaViska
16e7287c24 rework @watch decorator 2021-06-15 09:26:35 -04:00
Cory LaViska
3b2b5eed5a add test for sl-include 2021-06-15 09:11:04 -04:00
Cory LaViska
0521740824 fix preview imports 2021-06-14 17:17:41 -04:00
Cory LaViska
1d2033953b npm audit 2021-06-14 17:17:27 -04:00
Cory LaViska
e20edefc61 allow null 2021-06-10 09:50:30 -04:00
Cory LaViska
a9287d9d80 use a button 2021-06-10 09:34:13 -04:00
Cory LaViska
ba029db24e only open when key press is printable 2021-06-10 09:33:02 -04:00
Cory LaViska
529c187bc4 make imports consistent 2021-06-09 08:48:26 -04:00
Cory LaViska
714914ffe5 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-06-09 08:36:27 -04:00
Matthias Max
cd23b9ebfe Fix import path (#463) 2021-06-09 08:36:19 -04:00
Cory LaViska
35ce68f4f6 fix animation import example 2021-06-09 08:34:31 -04:00
Cory LaViska
f7bcd89b97 fixes #456 2021-06-05 12:29:57 -04:00
Cory LaViska
0b44fba68c cleanup listener 2021-06-05 12:28:35 -04:00
Cory LaViska
501869c7aa fixes #458 2021-06-04 09:33:43 -04:00
Cory LaViska
15cb1cb746 fixes #457 2021-06-04 08:56:35 -04:00
Cory LaViska
7454cc12a1 restore select docs 2021-06-04 08:19:28 -04:00
Cory LaViska
52d52810b9 2.0.0-beta.43 2021-06-03 14:14:53 -04:00
Cory LaViska
936039f7a7 update changelog 2021-06-03 14:14:11 -04:00
Cory LaViska
ba0e8f7973 add link 2021-06-03 11:55:56 -04:00
Cory LaViska
8449a99418 update splash 2021-06-03 11:55:47 -04:00
Cory LaViska
28c9dbab1f add initial tests 2021-06-03 08:42:51 -04:00
Cory LaViska
81753cd44b fixes #454 2021-06-03 07:38:05 -04:00
Cory LaViska
9970bc84ff fixes #452; fixes #453 2021-06-02 19:06:04 -04:00
Cory LaViska
499bc4c4cd fix comments 2021-06-02 19:05:47 -04:00
Cory LaViska
b0921b5be0 fixes #451 2021-06-02 08:47:55 -04:00
Cory LaViska
afc4dfaf50 use globby 2021-06-02 07:41:28 -04:00
Cory LaViska
9dda3a9323 remove unused lib 2021-06-02 07:41:18 -04:00
Cory LaViska
115e80dce0 fix scrollable tabs 2021-06-01 08:21:10 -04:00
Cory LaViska
9f405686ec fixes #450 2021-06-01 08:09:13 -04:00
Cory LaViska
e7d7469c4e make reflected types show up in docs 2021-05-30 09:46:09 -04:00
Cory LaViska
0dbb72efe9 add scrollPosition method 2021-05-29 10:55:56 -04:00
Cory LaViska
9b21d5a619 add ? to optional args 2021-05-29 10:54:55 -04:00
Cory LaViska
8ffcdebffc 2.0.0-beta.42 2021-05-28 22:09:46 -04:00
Cory LaViska
e089184a14 revert 2021-05-28 22:09:40 -04:00
Cory LaViska
a2a059962c 2.0.0-beta.43 2021-05-28 22:08:45 -04:00
Cory LaViska
3eb42321d5 exclude tests 2021-05-28 22:08:21 -04:00
Cory LaViska
474484b059 2.0.0-beta.42 2021-05-28 22:03:24 -04:00
Cory LaViska
998e255636 update version 2021-05-28 22:02:27 -04:00
Cory LaViska
3938644442 add tests to prepub 2021-05-28 22:02:17 -04:00
Cory LaViska
b13e637593 added tests for details 2021-05-28 21:53:38 -04:00
Cory LaViska
95e3f5e0e8 fixes #445 2021-05-28 21:53:20 -04:00
Cory LaViska
d5ee79fe1e remove unused custom props 2021-05-28 21:08:31 -04:00
Cory LaViska
51f003d5fd add test info 2021-05-28 20:45:32 -04:00
Cory LaViska
dd89657f1e fix popper positioning 2021-05-28 10:47:24 -04:00
Cory LaViska
1e280608d3 update changelog 2021-05-28 10:14:34 -04:00
Cory LaViska
c6e5bedd3c fixes #448 2021-05-28 10:13:46 -04:00
Cory LaViska
0ff5b46799 add test runner and initial alert tests 2021-05-27 17:52:19 -04:00
Cory LaViska
e34090a87b update lit/esbuild 2021-05-27 17:00:43 -04:00
Cory LaViska
f690b24c68 use glob and ignore test files 2021-05-27 16:50:58 -04:00
Cory LaViska
10f045fe6e fix show/hide logic 2021-05-27 16:29:10 -04:00
Cory LaViska
8d8b77ca07 fix icon search and debounce results 2021-05-27 07:28:30 -04:00
Cory LaViska
234d2380ef update changelog 2021-05-26 20:28:25 -04:00
Cory LaViska
4de659d5bb Add iconoir example 2021-05-26 20:27:16 -04:00
Cory LaViska
2aabe4e11c 2.0.0-beta.41 2021-05-26 19:57:07 -04:00
Cory LaViska
171e55ce6d update version 2021-05-26 19:56:07 -04:00
Cory LaViska
297e6c8872 npm audit 2021-05-26 19:55:44 -04:00
Cory LaViska
2b39d613b7 update docs 2021-05-26 19:53:56 -04:00
Cory LaViska
2432fd1d85 remove bad keyframe 2021-05-26 12:55:12 -04:00
Cory LaViska
3cc3d4997b update changelog 2021-05-26 12:49:30 -04:00
Cory LaViska
9c0189f8be fix disabled and destroy popovers 2021-05-26 12:49:20 -04:00
Cory LaViska
fc5a21f57d add guard to show/hide methods 2021-05-26 12:43:30 -04:00
Cory LaViska
ee9ce8a87b remove popover util 2021-05-26 12:43:03 -04:00
Cory LaViska
d720121044 update tooltip 2021-05-26 12:42:50 -04:00
Cory LaViska
3fce846a8d add parseDuration method 2021-05-26 12:41:52 -04:00
Cory LaViska
8776c3f4a8 destructure animation 2021-05-26 08:42:55 -04:00
Cory LaViska
189ad7889d update dropdown 2021-05-26 08:42:33 -04:00
Cory LaViska
79a15e1470 remove unused code 2021-05-26 08:17:28 -04:00
Cory LaViska
dfd0d0ed30 Merge branch 'next' into animation-rework 2021-05-26 07:53:57 -04:00
Cory LaViska
d7bf0bd653 fixes #443 2021-05-26 07:51:57 -04:00
Cory LaViska
6044190019 update changelog 2021-05-26 07:33:38 -04:00
Cory LaViska
89b8d0ef67 update template 2021-05-26 07:33:00 -04:00
Cory LaViska
489d713fa2 update tab group placements 2021-05-26 07:32:51 -04:00
Cory LaViska
8d984d8dac only support Keyframe[] 2021-05-26 07:32:31 -04:00
Cory LaViska
cadbae85a5 update drawer 2021-05-26 07:32:16 -04:00
Cory LaViska
01bb476023 slow it down 2021-05-26 07:31:42 -04:00
Cory LaViska
d5c37f7b29 update details 2021-05-26 07:31:26 -04:00
Cory LaViska
99181cf5c6 slow it down 2021-05-26 07:29:59 -04:00
Cory LaViska
7836b8229a Merge branch 'next' into animation-rework 2021-05-24 16:09:16 -04:00
Cory LaViska
3cff627b22 Merge branch 'current' into next 2021-05-24 16:08:59 -04:00
Cory LaViska
4263899bc0 parse decorator for attribute 2021-05-24 16:07:41 -04:00
Cory LaViska
0f4bb2b24b fix comment 2021-05-24 16:07:06 -04:00
Cory LaViska
7bd7b421b8 update syntax 2021-05-24 09:15:09 -04:00
Cory LaViska
49eb9bbcf8 fix metadata 2021-05-24 09:13:46 -04:00
Cory LaViska
a87596b3a1 Add animation registry and update alert/dialog 2021-05-21 17:53:53 -04:00
Cory LaViska
1ca890b1e9 rework alert animations 2021-05-19 13:46:18 -04:00
Cory LaViska
52aba14ae9 add animation utils 2021-05-19 13:46:03 -04:00
Cory LaViska
916ee07265 move custom property tags to main comment block 2021-05-17 18:04:28 -04:00
Cory LaViska
1e67c7411c add settings and recommended extensions for vs code 2021-05-17 09:03:18 -04:00
Cory LaViska
62ef8e17c7 remove resize observer types
These were finally added to TypeScript so they're no longer needed.
2021-05-17 09:02:59 -04:00
Cory LaViska
327ef6b06c fix typo 2021-05-13 10:51:50 -04:00
Cory LaViska
5dff7b2855 remove md extension from docs 2021-05-13 09:11:24 -04:00
Cory LaViska
22b359a612 update typedoc 2021-05-13 09:10:52 -04:00
Cory LaViska
7bf3a8d8f7 2.0.0-beta.40 2021-05-12 08:04:59 -04:00
Cory LaViska
4bd73ac374 update version 2021-05-12 08:04:07 -04:00
Cory LaViska
cae50866f9 remove global [hidden] styles 2021-05-12 07:42:44 -04:00
Cory LaViska
ebd1b95ba0 remove src/utilities/index 2021-05-12 07:33:56 -04:00
Cory LaViska
703cb4dc7a update typescript
=
2021-05-12 07:30:26 -04:00
Cory LaViska
e274904d28 use platform agnostic delete 2021-05-11 08:35:31 -04:00
Cory LaViska
b3bcfc9934 update bootstrap icons to 1.5.0 2021-05-10 12:43:31 -04:00
Cory LaViska
a3beaafbcc fixes #424 2021-05-10 09:31:53 -04:00
Cory LaViska
5c619b87b6 add responsive media component; fixes #436 2021-05-04 09:51:16 -04:00
Cory LaViska
86fc6b85d6 fix import bug; closes #439 2021-05-03 15:08:17 -04:00
Cory LaViska
4c1e077833 fixes #425 2021-05-03 11:32:59 -04:00
Cory LaViska
c8e94ea098 remove bypass logic 2021-05-03 11:32:38 -04:00
Cory LaViska
cf38478cd5 improve a11y 2021-05-03 11:28:57 -04:00
Cory LaViska
e3ca914eac remove null 2021-05-03 11:25:20 -04:00
Cory LaViska
18a933bf6b update attribution 2021-04-26 15:48:17 -04:00
Cory LaViska
7554f47258 Update React to use @shoelace-style/react 2021-04-26 11:48:24 -04:00
Cory LaViska
e579330177 update changelog 2021-04-26 07:07:57 -04:00
Cory LaViska
360cfa43d8 formatting corrections 2021-04-26 07:07:08 -04:00
Corbin Crutchley
f66535f7d4 Update NextJS docs for beta 39 (#434) 2021-04-26 07:04:24 -04:00
Cory LaViska
ce0b64045c 2.0.0-beta.39 2021-04-22 15:44:44 -04:00
Cory LaViska
b09bfdd01d update changelog 2021-04-22 15:42:23 -04:00
Cory LaViska
eeb1a097a3 udpate esbuild 2021-04-22 09:34:58 -04:00
Cory LaViska
0911299797 update lit 2021-04-22 08:18:51 -04:00
Cory LaViska
af601c6e9c Add system icon library (#420, #422)
* Add system icon library

* fixes #420

* update changelog
2021-04-20 09:37:19 -04:00
Cory LaViska
51d48b6aad 2.0.0-beta.38 2021-04-19 10:08:49 -04:00
Cory LaViska
a3d38c0e4b update version 2021-04-19 10:08:18 -04:00
Cory LaViska
19f01d29aa remove example 2021-04-18 16:01:27 -04:00
Cory LaViska
bf2a4ac6cb cache menu items for better performance 2021-04-15 14:27:35 -04:00
Cory LaViska
51c252420e refactor tabbable utils 2021-04-15 13:38:53 -04:00
Cory LaViska
a02354283b improve focus traps and a11y for dialog/drawer 2021-04-15 13:30:58 -04:00
Cory LaViska
121723b440 update changelog 2021-04-12 10:44:38 -04:00
Cory LaViska
3834f3a61a remove dot 2021-04-12 10:44:29 -04:00
Joël Billaud
a1c6035542 Fixes icon loading race (#411) 2021-04-12 10:40:36 -04:00
Cory LaViska
f2005bdcd8 fixes #407 2021-04-12 10:05:03 -04:00
Cory LaViska
9f42a698c4 fixes #409 2021-04-12 10:00:07 -04:00
Cory LaViska
2bbea51830 don't announce icon 2021-04-09 13:51:48 -04:00
Cory LaViska
70a94bb38e fix prefix/suffix spacing 2021-04-09 13:38:17 -04:00
Cory LaViska
b06f58db5f Add note about usage 2021-04-09 13:38:01 -04:00
Cory LaViska
75bd54d16a hide radio check in WHC mode 2021-04-09 08:48:25 -04:00
Cory LaViska
f4ccf86ece add role 2021-04-09 08:47:14 -04:00
Cory LaViska
b4fc01e99a add radio group 2021-04-09 08:15:33 -04:00
Cory LaViska
8e404bd478 2.0.0-beta.37 2021-04-07 17:07:10 -04:00
Cory LaViska
4555406143 update version 2021-04-07 17:06:46 -04:00
Cory LaViska
8f8cf9649d fixes #403 2021-04-07 17:05:38 -04:00
Cory LaViska
9b8bee2bc5 add create script 2021-04-07 17:03:24 -04:00
Cory LaViska
5bea4269a7 don't break if dependency doesn't exist 2021-04-07 12:56:44 -04:00
Cory LaViska
0b4dc3f6a8 fixes #401 2021-04-07 10:01:31 -04:00
Cory LaViska
c2314e9871 improve aria-labelledby for form controls 2021-04-05 17:13:17 -04:00
Cory LaViska
4b4361c514 Add pink button styling example 2021-04-05 16:59:11 -04:00
Cory LaViska
8d2d8cd9f0 add activation prop 2021-04-05 16:58:33 -04:00
Cory LaViska
d59fdbc443 remove unused import 2021-04-02 14:42:01 -04:00
Cory LaViska
16add89462 improve button group divider color 2021-04-02 14:41:51 -04:00
Cory LaViska
16a3d5f156 fix default values 2021-04-02 07:47:25 -04:00
Cory LaViska
19b0c7978f rename toast stack stylesheet 2021-04-02 07:33:36 -04:00
Cory LaViska
7a64963fef rework button group to not use light DOM styles 2021-04-02 07:24:59 -04:00
Cory LaViska
48216a4fdc allow dropdown events to bubble 2021-04-01 09:50:38 -04:00
Cory LaViska
b2599d5a9f remove unused events 2021-04-01 09:50:33 -04:00
Cory LaViska
2e893bbaf2 fix show/hide when disabled 2021-04-01 09:50:29 -04:00
Cory LaViska
26bfe8ef11 fix event names 2021-04-01 09:50:23 -04:00
Cory LaViska
784c173728 add click method 2021-04-01 09:50:18 -04:00
Cory LaViska
619758cbc3 improve a11y 2021-04-01 09:49:36 -04:00
Cory LaViska
d1ab1e5cc2 fixes #391 2021-04-01 09:49:31 -04:00
Cory LaViska
261f6bb322 cleanup events 2021-04-01 09:49:27 -04:00
Cory LaViska
e4a4281200 fix default values 2021-04-01 07:57:31 -04:00
Cory LaViska
dac05f8d06 improve a11y 2021-04-01 07:50:27 -04:00
Cory LaViska
3c9a4812ca fixes #391 2021-04-01 07:38:17 -04:00
Cory LaViska
0208cf6229 cleanup events 2021-04-01 07:20:37 -04:00
Cory LaViska
1282deabd0 improve a11y for button links 2021-03-31 12:03:20 -04:00
Cory LaViska
d6e109b895 2.0.0-beta.36 2021-03-30 09:30:47 -04:00
Cory LaViska
7a512232c4 update version 2021-03-30 09:30:16 -04:00
Cory LaViska
75d1abaa9c fixes #357 2021-03-30 09:30:00 -04:00
Cory LaViska
485a7252b0 reorder 2021-03-30 09:11:35 -04:00
Cory LaViska
0935e1574a rename setFocus and removeFocus methods 2021-03-30 09:09:52 -04:00
Cory LaViska
a04fc7c681 fixes #388, #fixes #389 2021-03-30 09:03:36 -04:00
Cory LaViska
a71f28c664 update sprite 2021-03-30 08:52:03 -04:00
Cory LaViska
e00997ce97 update bootstrap-icons 2021-03-30 08:49:58 -04:00
Cory LaViska
c50b57d96b tidy up color picker 2021-03-30 08:44:41 -04:00
Cory LaViska
3bd3bdd086 cleanup 2021-03-30 08:34:44 -04:00
Cory LaViska
d059017153 update changelog 2021-03-30 08:33:43 -04:00
Cory LaViska
28c0121a69 add open watcher 2021-03-30 08:33:08 -04:00
Cory LaViska
560441bea3 fix attr 2021-03-30 08:29:54 -04:00
Cory LaViska
7518e07882 rename components.json 2021-03-25 08:15:26 -04:00
Cory LaViska
25f63df53a fix link button events 2021-03-24 11:33:44 -04:00
Cory LaViska
9e325dffa0 simplify code block logic 2021-03-24 11:26:20 -04:00
Cory LaViska
389dd0b44e update to lit-element and lit-html prerelease 2021-03-24 10:21:21 -04:00
Cory LaViska
59dd5c0c3e 2.0.0-beta.35 2021-03-23 17:14:38 -04:00
Cory LaViska
1b2e92c153 Update version 2021-03-23 17:14:03 -04:00
Cory LaViska
f3db9e92ee update docs 2021-03-23 13:52:15 -04:00
Cory LaViska
cb156dc84a make sl-resize-observer stable 2021-03-23 08:43:38 -04:00
Cory LaViska
494be4f25b fix active tab indicator position 2021-03-22 17:26:56 -04:00
Cory LaViska
35cde2c3c3 update 2021-03-22 15:12:14 -04:00
Cory LaViska
401eaf0a63 refactor 2021-03-22 13:14:32 -04:00
Cory LaViska
a2e3fe70d5 Remove v1 link 2021-03-22 13:13:07 -04:00
Cory LaViska
5fd4bca95d run watch decorator after update completes 2021-03-22 11:39:11 -04:00
Cory LaViska
2fbd2af914 Use default check icon 2021-03-22 11:35:50 -04:00
Cory LaViska
a9886851d5 Fix event bug 2021-03-22 11:23:58 -04:00
Cory LaViska
b935a0a838 fix alert transitions 2021-03-22 11:03:24 -04:00
Cory LaViska
db2005d239 revert indexOf change 2021-03-22 10:30:47 -04:00
Cory LaViska
20eff47286 fixes #382 2021-03-22 08:31:01 -04:00
Cory LaViska
2cf65ff2dd fix spacing 2021-03-18 19:03:29 -04:00
Cory LaViska
a4a2ff948f 2.0.0-beta.34 2021-03-18 09:08:11 -04:00
Cory LaViska
c351e56aa7 fix stylesheet refs 2021-03-18 09:06:36 -04:00
Cory LaViska
334a7ca832 reenable autoregistration 2021-03-18 09:04:23 -04:00
Cory LaViska
119245e7ac remove unused metadata 2021-03-17 12:31:08 -04:00
Cory LaViska
cffa6726db fix attribs 2021-03-16 09:16:11 -04:00
Cory LaViska
b05d1967d0 fixed validation bug 2021-03-16 09:03:15 -04:00
Cory LaViska
42f646eaaa add sl-clear event 2021-03-16 08:23:23 -04:00
Cory LaViska
e7cea10e17 fix margin 2021-03-15 17:49:44 -04:00
Cory LaViska
f50d354ceb fix label when items are dynamically added 2021-03-15 17:48:58 -04:00
Cory LaViska
8aa9466d6b 2.0.0-beta.33 2021-03-15 13:04:03 -04:00
Cory LaViska
7ba0f51e9e update version 2021-03-15 13:03:49 -04:00
Cory LaViska
a67db7e13e fix setFocus() method on button 2021-03-15 13:03:01 -04:00
Cory LaViska
57b561b353 add type 2021-03-15 13:02:49 -04:00
Cory LaViska
f372e36a79 fix tag shapes 2021-03-15 08:03:32 -04:00
Cory LaViska
85e2142a56 create next section 2021-03-15 07:58:46 -04:00
Cory LaViska
83b38987cc fix props 2021-03-15 07:56:15 -04:00
Cory LaViska
30132ed9ea 2.0.0-beta.32 2021-03-12 09:10:32 -05:00
Cory LaViska
1193ba6bb0 update version 2021-03-12 09:10:15 -05:00
Cory LaViska
a70e1ae856 update changelog 2021-03-12 09:09:55 -05:00
Cory LaViska
0213eb2376 prettier 2021-03-12 09:09:08 -05:00
ibirrer
a14346ea87 declare types for component tags (#371) 2021-03-12 09:07:38 -05:00
Cory LaViska
0234fe81d5 fix watch handlers 2021-03-11 12:56:45 -05:00
Cory LaViska
0489d8b5c0 fixes #370 2021-03-11 12:51:41 -05:00
Cory LaViska
93a5be1ce8 light tab group refactor 2021-03-11 09:20:54 -05:00
Nils Silbernagel
e15bd8bca1 fix tab group indicator position (#366)
* fix tab group indicator position for flex-end

* fix event type parsing

* update version

* 2.0.0-beta.31

* tab-group resize reposition active tab indicator

* tab-group remove transition constant

Co-authored-by: Nils Silbernagel <n.silbernagel@awesome-software.de>
Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
2021-03-11 09:11:06 -05:00
Cory LaViska
3b3aef7c63 remove guards that were added for old @watch 2021-03-11 08:58:30 -05:00
Cory LaViska
c5614bfc95 only run handler after first render 2021-03-11 08:57:33 -05:00
Cory LaViska
7fb1a83788 2.0.0-beta.31 2021-03-10 08:34:47 -05:00
Cory LaViska
0114261fa1 update version 2021-03-10 08:34:06 -05:00
Cory LaViska
d5af772444 fix event type parsing 2021-03-10 08:33:50 -05:00
Cory LaViska
7b907bc326 fixes #357 2021-03-09 12:52:36 -05:00
Cory LaViska
fca8c2fdce update changelog 2021-03-09 09:22:51 -05:00
Cory LaViska
5f310ddab2 reorder methods, cleanup, and prevent dragging 2021-03-09 09:22:41 -05:00
Nils Silbernagel
cdbae1fca3 add touch support to sl-rating (#362)
* add touch support to `sl-rating`
2021-03-09 09:17:27 -05:00
Cory LaViska
3f8048fe41 reword 2021-03-08 20:06:09 -05:00
Cory LaViska
b4d51e7ea7 reword 2021-03-08 19:59:50 -05:00
Cory LaViska
a9d7258a07 fix typo 2021-03-08 19:54:58 -05:00
Cory LaViska
6940713e36 2.0.0-beta.30 2021-03-08 19:20:02 -05:00
Cory LaViska
32e4bfe83c update comment 2021-03-08 19:19:34 -05:00
Cory LaViska
28965a422d fix default exports for all components 2021-03-08 19:14:32 -05:00
Cory LaViska
3c4ec12b18 revert FOUC styles 2021-03-08 19:10:39 -05:00
Matthias Max
cc24f7ade0 fix typo (#356) 2021-03-08 09:26:08 -05:00
Cory LaViska
d1d1a4d03e 2.0.0-beta.29 2021-03-08 09:12:47 -05:00
Cory LaViska
ce88f2c828 update changelog 2021-03-08 09:09:38 -05:00
Cory LaViska
935796c545 add guard 2021-03-08 09:08:29 -05:00
Cory LaViska
e40744c9ff add guard 2021-03-08 09:06:35 -05:00
Cory LaViska
169b2867fc revert active styles 2021-03-08 08:45:19 -05:00
Cory LaViska
c0ec00a0fc fix event details metadata 2021-03-08 08:21:13 -05:00
Cory LaViska
a0ea729bb9 use @tag instead of @customElement for treeshaking 2021-03-08 07:51:31 -05:00
Cory LaViska
c53634544a add tag decorator and merge 2021-03-08 07:50:58 -05:00
Cory LaViska
59cdafd722 Fix vertical padding in tooltip 2021-03-07 09:20:20 -05:00
Cory LaViska
8e8b692128 Update tooltip 2021-03-07 09:20:04 -05:00
Cory LaViska
060936d611 less is more 2021-03-07 09:10:45 -05:00
Cory LaViska
47a8b3f19a fix dev build 2021-03-07 09:02:57 -05:00
Cory LaViska
dafb10b1ce update changelog 2021-03-07 08:54:30 -05:00
Cory LaViska
7d66a031a3 add comment 2021-03-07 08:54:07 -05:00
Cory LaViska
9bd703014c Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-03-07 08:41:01 -05:00
Andreas
1d174cfdf5 fix css custom prop name in docs (#360)
* fix css custom prop name in docs

to see the actual custom property again instead of the string 'prop'

* remove trailing colon from property name
2021-03-07 08:38:38 -05:00
Cory LaViska
e903c82133 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-03-07 08:24:22 -05:00
Lorefnon
fbbfeb00db Add back TS declarations (#364) 2021-03-07 08:23:43 -05:00
Cory LaViska
6c39dce582 Update table heading 2021-03-06 16:37:53 -05:00
Cory LaViska
405f38573a Fix metadata comments 2021-03-06 16:37:39 -05:00
Cory LaViska
18859be955 fix reflections 2021-03-06 15:34:33 -05:00
Cory LaViska
786ba8a2fb don't reflect name 2021-03-06 15:26:34 -05:00
Cory LaViska
96091e42ff add guard 2021-03-06 15:23:06 -05:00
Cory LaViska
6062e73022 fix boolean attribs 2021-03-06 15:22:59 -05:00
Cory LaViska
4673e726a9 fix kebab case attribs 2021-03-06 15:18:54 -05:00
Cory LaViska
f10051b588 fix doc comment 2021-03-06 15:11:15 -05:00
Cory LaViska
4ef21c2852 update old watch syntax 2021-03-06 15:09:12 -05:00
Cory LaViska
6283d14758 add @watch decorator 2021-03-06 14:39:48 -05:00
Cory LaViska
3bb38e74e3 pass value as property 2021-03-06 12:39:24 -05:00
Cory LaViska
a4f64b91eb fix self-closing tags 2021-03-06 12:39:13 -05:00
Cory LaViska
2f4d93700a migrate to LitElement 2021-03-06 12:01:39 -05:00
Cory LaViska
099dfc93d8 show typedoc output on error 2021-03-04 09:08:43 -05:00
Cory LaViska
d4f5a170f5 prevent FOUC 2021-03-04 07:29:19 -05:00
Cory LaViska
0bccc051d2 generate metadata and fix code completion 2021-03-03 16:56:42 -05:00
Cory LaViska
9e3a573b53 fix typo 2021-03-03 07:59:40 -05:00
Cory LaViska
1f9771a2d6 Move chunks to separate folder 2021-03-02 17:23:49 -05:00
Cory LaViska
ffebe1583e 2.0.0-beta.28 2021-02-26 09:10:16 -05:00
Cory LaViska
fe45f2159f Shoemaker rework 2021-02-26 09:09:13 -05:00
Cory LaViska
4eeeffc493 Fix drawer overlay click 2021-02-24 07:14:24 -05:00
Per Karlsson
b15078030c Make dialog overlay non focusable (#344)
If you click the overlay in the [ignore clicks on the overlay](https://shoelace.style/components/dialog?id=ignoring-clicks-on-the-overlay) demo you can no longer press escape to close the modal since the overlay has been focused.
2021-02-24 07:12:12 -05:00
Cory LaViska
2a9a9d7da2 fixes #340 2021-02-22 07:14:31 -05:00
Cory LaViska
6a52bdd6ea Fixes #325 2021-02-10 11:25:13 -05:00
Cory LaViska
054cfe3a85 2.0.0-beta.27 2021-02-10 09:28:57 -05:00
Cory LaViska
4e8b2abb54 Update version 2021-02-10 09:28:20 -05:00
Cory LaViska
6b40f4b2f4 Update changelog 2021-02-10 09:26:27 -05:00
ibirrer
58b4b398d5 Emit sl-error in sl-icon for failing requests (#326) 2021-02-10 09:24:57 -05:00
Cory LaViska
d093b8a4de Update changelog 2021-02-08 11:02:21 -05:00
Cory LaViska
63fdf71010 Update example 2021-02-08 11:01:47 -05:00
Cory LaViska
dc0edc597f Fix target logic 2021-02-08 11:01:30 -05:00
Cory LaViska
295e2cd1c5 Reduce tooltip default line-height 2021-02-08 11:00:35 -05:00
Cory LaViska
425a327b45 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2021-02-08 10:37:59 -05:00
Denis Korablev
4e5b0e06dc Add content slot to tooltip (#322) 2021-02-08 10:37:50 -05:00
Cory LaViska
7c819f05e5 Update changelog 2021-02-08 10:32:35 -05:00
Corbin Crutchley
f73f152031 Added initial NextJS documentation (#314) 2021-02-08 10:28:54 -05:00
Cory LaViska
5283b5a808 Fixes #323 2021-02-05 16:09:05 -05:00
Cory LaViska
96e352d034 Update Stencil to 2.4.0 2021-02-04 10:24:19 -05:00
Cory LaViska
9b49ca6eb0 Add label and helpText to range 2021-02-04 10:22:04 -05:00
Nicolás Font
a9059d2dd1 Fix typo in usage.md (#315) 2021-01-31 14:59:21 -05:00
Cory LaViska
9bea517ae8 Fixes #313 2021-01-25 16:06:43 -05:00
Cory LaViska
78bcd0fe9e Add handle-icon slot to image comparer 2021-01-25 08:56:59 -05:00
Cory LaViska
ec1f7f5ddf Allow tags to wrap for multiselect 2021-01-21 09:40:33 -05:00
Cory LaViska
ef65f0e7be Fix menu toggle when clearing tags 2021-01-20 12:09:48 -05:00
Cory LaViska
63eb5a773f Improve menu item focus color 2021-01-20 12:06:03 -05:00
Cory LaViska
a64b57245c Update social media images 2021-01-20 11:23:34 -05:00
Cory LaViska
23d6e640de 2.0.0-beta.26 2021-01-18 14:06:40 -05:00
Cory LaViska
f94e0cc9ef Update version 2021-01-18 14:05:49 -05:00
Cory LaViska
3a8e39c7e9 Fix error on close 2021-01-18 14:03:59 -05:00
Cory LaViska
3f3ad6fd98 Add closable example 2021-01-18 13:49:04 -05:00
Cory LaViska
b400c40eb7 Fix error on click 2021-01-18 13:34:41 -05:00
Cory LaViska
3ea5a0dfd8 Update generated file 2021-01-18 13:23:56 -05:00
Cory LaViska
7edd99bf31 Remove text from badge types 2021-01-13 18:01:36 -05:00
Cory LaViska
6e93498e7b Reflect active prop 2021-01-11 12:18:25 -05:00
Cory LaViska
30a17ff655 Fix indentation 2021-01-11 12:17:27 -05:00
Cory LaViska
9f537777d4 Use transitionend instead of a timeout 2021-01-11 08:09:05 -05:00
Cory LaViska
a5ab18748b Export icon button parts so they can be customized 2021-01-10 12:30:27 -05:00
Cory LaViska
64dfe9e648 Add close-button part to tab; fixes #303 2021-01-10 12:14:46 -05:00
Cory LaViska
3fd2ab1991 Fix transitions in Safari 2021-01-08 10:25:29 -05:00
Cory LaViska
d3e378506e Add preventScroll check 2021-01-08 10:24:39 -05:00
Cory LaViska
70c7560f60 Update bootstrap-icons to 1.3.0 2021-01-07 17:05:41 -05:00
Cory LaViska
4a29ecafb6 Remove coverage flag 2021-01-07 12:21:21 -05:00
Cory LaViska
fc8e48cb6a Add sl-initial-focus to dialog + drawer 2021-01-07 10:17:08 -05:00
Cory LaViska
abf03a8f9e Add FocusOptions to setFocus() methods 2021-01-07 10:13:08 -05:00
Cory LaViska
da20e44d52 Add subdependencies 2021-01-06 13:25:59 -05:00
Cory LaViska
d578f63350 Show dependencies not dependents 2021-01-06 12:59:36 -05:00
Cory LaViska
6053244cd8 Move custom elements bundle 2021-01-06 12:41:01 -05:00
Cory LaViska
d1dbe24e62 Add avatar group example 2021-01-06 07:57:46 -05:00
Cory LaViska
fb38bc4c0a Remove www output target 2021-01-06 07:19:04 -05:00
Cory LaViska
96c66d11ce Add nested tab group test 2021-01-05 08:51:44 -05:00
Cory LaViska
a0e929787e Fix nested tab group bug 2021-01-05 08:41:56 -05:00
Cory LaViska
1d2a180467 Remove test from prebuild 2021-01-04 14:13:49 -05:00
Cory LaViska
1752e274e4 Fix promise return values 2021-01-04 14:13:36 -05:00
Cory LaViska
a2c25acfd9 Fix promise return values 2021-01-04 14:11:23 -05:00
Cory LaViska
9f7d4be683 Update changelog 2020-12-30 13:53:44 -05:00
Cory LaViska
8912cc1886 Prevent sl-hide from being emitted twice 2020-12-30 13:53:33 -05:00
Cory LaViska
d5ff10eca0 Run tests before build 2020-12-30 13:50:00 -05:00
Cory LaViska
a54ca48f35 Update and move tests 2020-12-30 13:32:42 -05:00
Cory LaViska
262fa463f6 Remove dup 2020-12-30 08:39:43 -05:00
Cory LaViska
1fb2bfe948 Merge branch 'tests' of https://github.com/lamplightdev/shoelace into lamplightdev-tests 2020-12-30 08:37:44 -05:00
Cory LaViska
e04aeb62d9 Fix toggle button size in Safari 2020-12-29 15:40:04 -05:00
Cory LaViska
7ad4f55a89 Fix mobile view 2020-12-29 15:26:47 -05:00
Cory LaViska
9232f35ccc Fix animations bloat 2020-12-29 15:21:15 -05:00
Cory LaViska
201f7a8064 Add metadata 2020-12-29 14:57:45 -05:00
Cory LaViska
353b57513e Add discussion forum info 2020-12-28 14:42:31 -05:00
Cory LaViska
d7fc65ed89 2.0.0-beta.25 2020-12-23 17:05:30 -05:00
Cory LaViska
37b6b55234 Update changelog 2020-12-23 17:04:29 -05:00
Cory LaViska
d2dfded69e Fix tooltip demo 2020-12-23 16:57:58 -05:00
Cory LaViska
b888e3c4e6 Fix nested list margins 2020-12-23 15:56:58 -05:00
Cory LaViska
c5278a40f9 Update changelog 2020-12-23 15:48:21 -05:00
Cory LaViska
8fc6c26699 Update bootstrap-icons 2020-12-23 15:48:09 -05:00
Cory LaViska
b16d262ec8 Refactor label + help text logic 2020-12-23 15:47:13 -05:00
Cory LaViska
e9b1463f0c Use spacing tokens 2020-12-23 12:08:57 -05:00
Cory LaViska
32624b74fe Remove empty rules 2020-12-23 10:48:06 -05:00
Cory LaViska
11846f307d Move resize observer types to dependencies 2020-12-23 09:15:18 -05:00
Cory LaViska
4754f368a0 Add behavior param 2020-12-23 09:07:08 -05:00
Cory LaViska
3883be3193 Add visual separators for solid buttons 2020-12-23 08:48:48 -05:00
Cory LaViska
9f7bc29b5f Fix element 2020-12-22 17:40:49 -05:00
Cory LaViska
48eeb9ecd0 Improve button spacing 2020-12-22 17:40:37 -05:00
Cory LaViska
23d9ff9096 Add default slot detection to hasSlot 2020-12-22 17:09:01 -05:00
Cory LaViska
0aa1c9a741 Improve slot detection 2020-12-22 17:08:19 -05:00
Cory LaViska
523aa6cdf6 Escape should dismiss tooltips; fixes #219 2020-12-22 14:41:22 -05:00
Cory LaViska
fcd432d8b7 Rework color tokens 2020-12-22 09:40:11 -05:00
Cory LaViska
4ebd15121e Add shoelace tag 2020-12-22 09:15:31 -05:00
Cory LaViska
05f8b8933b Rename noToggle => noFormatToggle 2020-12-21 17:23:14 -05:00
Cory LaViska
ba27097315 Add color types 2020-12-16 08:21:01 -05:00
Cory LaViska
f106d85320 Make TS happy 2020-12-16 08:20:49 -05:00
Cory LaViska
fc8232254f Add setting example 2020-12-16 08:00:28 -05:00
Cory LaViska
b4afb246ce Fix icon name/src removal bug; closes #285 2020-12-15 17:41:22 -05:00
Cory LaViska
2d4e1357ce Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2020-12-15 17:30:03 -05:00
Cory LaViska
3afcab586f Update icon count 2020-12-14 17:00:08 -05:00
Cory LaViska
5ee434462a Fix icon dropdown 2020-12-14 16:59:38 -05:00
Cory LaViska
255d3dd075 Update bootstrap-icons 2020-12-14 16:59:22 -05:00
Cory LaViska
817f52ae7f Fix toggle button styles in dark mode 2020-12-14 16:40:39 -05:00
Vladimir Dementyev
c7da2f24d5 Fix asset path for Rails (#268)
The path to assets should be consistent and not depend on the current script source. There are at least two situations when this assumption fails:
- When running `webpacker-dev-server`, the _pack_ URL doesn't contain `/js/` part.
- In test environment, `/packs-test` is used by default.
2020-12-12 11:21:36 -05:00
Cory LaViska
ea0aef46fd Use input instead of select for validation 2020-12-11 17:30:34 -05:00
Cory LaViska
248f494865 Reword 2020-12-11 17:24:31 -05:00
Cory LaViska
c21fd51f65 Fix typo 2020-12-11 17:23:41 -05:00
Cory LaViska
c80036b9fb Revert color picker trigger to circle 2020-12-11 17:14:11 -05:00
Cory LaViska
9f244131df Add format toggle and update styles 2020-12-11 17:10:30 -05:00
Cory LaViska
cb8e2c0197 Prevent dropdown trigger from losing focus 2020-12-11 17:10:06 -05:00
Cory LaViska
770a109a85 Fix menu item color 2020-12-11 17:09:28 -05:00
Cory LaViska
5b381eb1b7 Rework select; fixes #216 2020-12-11 17:09:10 -05:00
Cory LaViska
c7368fcbc1 Remove unused menu methods 2020-12-10 17:36:39 -05:00
Cory LaViska
08846f5c8a 2.0.0-beta.24 2020-12-09 09:21:39 -05:00
Cory LaViska
5076819dcd Update version 2020-12-09 09:20:34 -05:00
Cory LaViska
cd53b6830c Fix link 2020-12-09 08:18:59 -05:00
Cory LaViska
80a3eb8105 Upgrade to stable 2020-12-09 08:17:49 -05:00
Cory LaViska
23035aa434 Fix handle 2020-12-09 08:17:18 -05:00
Cory LaViska
662d0a3c79 Add allow-scripts prop to sl-include 2020-12-08 09:18:29 -05:00
Cory LaViska
3d71f535f3 Update attr tooltip 2020-12-08 09:17:17 -05:00
Cory LaViska
81ae77f686 Remove resize-observer-polyfill 2020-12-07 17:29:55 -05:00
Cory LaViska
08054036a6 Update spinner styles 2020-12-03 09:35:41 -05:00
Cory LaViska
3d8dd415a5 fixes #277 2020-12-02 17:17:34 -05:00
Cory LaViska
1a5634b237 Fixes #276 2020-11-30 09:00:43 -05:00
Cory LaViska
193f31b7fe Fix prop in docs 2020-11-30 08:57:13 -05:00
Cory LaViska
7c27f12b99 Update changelog 2020-11-25 16:20:55 -05:00
Cory LaViska
a64dc5a421 Add indeterminate state; closes #274 2020-11-25 16:20:15 -05:00
Cory LaViska
beb3915a80 Update docs 2020-11-25 16:19:00 -05:00
Cory LaViska
b7f70fcf8a Add sl-format-date component 2020-11-25 16:18:07 -05:00
Cory LaViska
511fd2ac7e Fix typos 2020-11-25 16:16:03 -05:00
Cory LaViska
8e0f743557 Fix changelog 2020-11-25 09:26:52 -05:00
Cory LaViska
cc0daef254 Prevent sl-hide from firing twice; fixes #275 2020-11-25 09:26:01 -05:00
Cory LaViska
c18b3b6f9d Remove original changelog file 2020-11-25 09:24:42 -05:00
Cory LaViska
3259faec06 Fixes #272 2020-11-23 09:44:49 -05:00
Cory LaViska
540f29c4e2 2.0.0-beta.23 2020-11-20 17:04:57 -05:00
Cory LaViska
b4795a8d2f Update version 2020-11-20 17:03:28 -05:00
Cory LaViska
96e255a571 Merge branch 'relative-time' into next 2020-11-20 17:02:59 -05:00
Cory LaViska
058e8fa08e Finish up sl-relative-time 2020-11-20 17:02:38 -05:00
Cory LaViska
410b39ee59 Update docs 2020-11-20 17:02:03 -05:00
Cory LaViska
6e759cc504 Update docs 2020-11-20 16:37:56 -05:00
Cory LaViska
df431321f5 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2020-11-16 21:33:01 -05:00
Matthias Max
db12476a0f fix css var name (#270) 2020-11-16 21:32:02 -05:00
Cory LaViska
8a08302bb7 Scaffold relative time component 2020-11-11 17:31:53 -05:00
Cory LaViska
72c77446c4 Fix docs 2020-11-11 17:31:16 -05:00
Cory LaViska
0e44d0fb7d Update generated file 2020-11-11 16:52:47 -05:00
Cory LaViska
0e66071def Fix github rate limit issue 2020-11-11 16:52:02 -05:00
Cory LaViska
a8deeb0659 Minor fixes 2020-11-10 09:33:16 -05:00
Cory LaViska
4e2cf2e9de Add format number component 2020-11-09 09:38:30 -05:00
Cory LaViska
97ad8f1b1b Update label 2020-11-09 09:37:58 -05:00
Cory LaViska
c06ad3cf7c Fix grip icon 2020-11-09 09:37:39 -05:00
Cory LaViska
64dfb008b2 Update to Stencil 2.3.0 2020-11-06 16:31:36 -05:00
Cory LaViska
c82dd0bb3c Fix autocomplete select bug 2020-11-05 09:10:02 -05:00
Thomas Klemm
688802b792 Fix Rails Integration docs: Missing module export statement (#263)
Thanks for this great library @claviska! 

Tried adding Shoelace to a Rails app w/ the current guide. When starting the Webpack Dev Server, the following error gets thrown:

```
.../RailsApplication/config/webpack/development.js:5
module.exports = environment.toWebpackConfig()
```
Adding `module.exports = environment` as done [here in the example repo](4114da0e14/config/webpack/environment.js (L20)) fixes the issue and allows Webpack to compile.
2020-11-05 08:14:25 -05:00
Cory LaViska
73dddc42db Fix closable styles 2020-11-02 09:06:27 -05:00
Cory LaViska
79f86792ce Add closable prop to tab 2020-11-02 08:32:54 -05:00
Cory LaViska
0433fe236d Simplify resize observer demo 2020-10-30 17:04:00 -04:00
Cory LaViska
4adb6bbf04 Add experimental resize observer 2020-10-29 18:15:48 -04:00
Cory LaViska
b5c92a1713 Update bootstrap-icons 2020-10-29 08:03:13 -04:00
Cory LaViska
1aa0710fc5 Add sl-theme component 2020-10-28 09:11:29 -04:00
Cory LaViska
264356afce Improve placeholder contrast 2020-10-28 08:30:39 -04:00
Cory LaViska
db6ed43648 Fix menu item dark theme 2020-10-28 07:48:51 -04:00
Cory LaViska
caf6493ae7 Update Stencil 2020-10-27 18:07:25 -04:00
Cory LaViska
d014da553a Fix version number 2020-10-27 08:49:10 -04:00
Cory LaViska
d438fb49f3 2.0.0-beta.22 2020-10-27 08:44:03 -04:00
Cory LaViska
4ceea86197 Use rem for input height and spacing; fixes #221 2020-10-27 08:35:46 -04:00
Cory LaViska
3828c070fc npm audit 2020-10-27 08:29:46 -04:00
Cory LaViska
cb1ab2ae7d Update Stencil 2020-10-27 08:21:46 -04:00
Cory LaViska
0d353cae6b Hide icon from screen readers 2020-10-27 08:21:04 -04:00
Cory LaViska
ad40f432ed Fix position bug 2020-10-27 08:07:14 -04:00
Cory LaViska
4e22d8001f Fix typo 2020-10-23 00:17:50 -04:00
Cory LaViska
4083395681 Add issue links 2020-10-23 00:17:19 -04:00
Cory LaViska
6b5c5aad5f Fix aria-describedby in tooltip targets 2020-10-22 23:26:23 -04:00
Cory LaViska
c9d0905b44 Fix typo 2020-10-22 23:05:28 -04:00
Cory LaViska
f32b8b3cfb Improve icon button accessibility 2020-10-22 23:03:38 -04:00
Cory LaViska
ee2c18d51c Fix boolean aria attribs 2020-10-22 22:45:41 -04:00
Cory LaViska
d66f120f78 Fix initial open state in dialog/drawer; closes #255 2020-10-22 21:54:26 -04:00
Cory LaViska
e6cee521ad Prevent rendering warning 2020-10-22 21:52:41 -04:00
Cory LaViska
f11b4b53d0 Add no-scroll-controls prop; fixes #253 2020-10-22 14:00:06 -04:00
Cory LaViska
3920d18286 Improve tooltip text 2020-10-22 13:56:24 -04:00
Cory LaViska
e40b20f10d Fix dropdown keyboard nav 2020-10-22 13:42:52 -04:00
Cory LaViska
7b5fc2451b Fix select keyboard nav 2020-10-22 13:42:37 -04:00
Cory LaViska
5d73537e09 Improve menu/menu item a11y 2020-10-22 13:41:09 -04:00
Cory LaViska
4e2ebb70af Fix dropdown positioning bug; closes #252 2020-10-19 10:30:59 -04:00
Cory LaViska
a8ca9c1d21 Improve dropdown a11y 2020-10-16 17:04:35 -04:00
Cory LaViska
7bc286da3e Don't announce dividers as menu items 2020-10-16 17:03:30 -04:00
Cory LaViska
7d20996781 Fix disabled prop 2020-10-16 12:32:20 -04:00
Cory LaViska
19243939a1 Remove console.log 2020-10-16 10:00:58 -04:00
Cory LaViska
938c02a889 2.0.0-beta.21 2020-10-16 09:30:41 -04:00
Cory LaViska
f342785a0a Update changelog 2020-10-16 09:29:35 -04:00
Cory LaViska
79c2660d06 Add try/catch 2020-10-16 09:29:07 -04:00
Cory LaViska
dcd987b738 Add status to sl-error; rework request logic 2020-10-16 09:28:46 -04:00
Cory LaViska
3bde111277 Remove unintended interface exports 2020-10-16 09:17:04 -04:00
Cory LaViska
c65346d8dd Move request logic to separate file 2020-10-16 09:16:43 -04:00
Cory LaViska
3514e88dcd Add sl-include 2020-10-16 08:57:02 -04:00
Cory LaViska
e22763ea37 Use console instead of throw 2020-10-16 07:44:25 -04:00
Cory LaViska
08bcdd9c93 Throw error when no tags are found 2020-10-16 07:36:43 -04:00
Cory LaViska
08bb1a088e Add label slot to dialog and drawer 2020-10-15 16:54:38 -04:00
Cory LaViska
272c7df91b Remove dead code comment 2020-10-15 16:35:25 -04:00
Cory LaViska
2bd88b7d92 Rework slot logic 2020-10-15 16:35:11 -04:00
Cory LaViska
4f23b49163 Improve types in docs 2020-10-15 16:34:09 -04:00
Cory LaViska
9b4fdbe16a Fix event names 2020-10-15 14:33:30 -04:00
Cory LaViska
2d393c0499 Fix tab stops in hidden components 2020-10-15 14:32:37 -04:00
Cory LaViska
cf2cf8edb0 Fix concurrent active modals bug 2020-10-15 13:55:42 -04:00
Cory LaViska
df0101cad2 Add modal utility 2020-10-15 13:54:20 -04:00
Cory LaViska
494ed99b36 Remove incorrect aria attribs 2020-10-15 12:35:48 -04:00
Cory LaViska
912b4167d7 Add label slot to input, select, textarea; closes #248 2020-10-15 11:44:41 -04:00
Cory LaViska
41bbdac940 Fix prettier version 2020-10-15 09:18:42 -04:00
Cory LaViska
309c413f76 Fix indeterminate state bug 2020-10-15 09:18:20 -04:00
Cory LaViska
5e8db633b9 Rework alert show/hide logic; #247 2020-10-13 12:41:57 -04:00
Cory LaViska
4f7496b6be Add modal keyword to improve search 2020-10-13 09:12:31 -04:00
Cory LaViska
777d8e540d Rename var for consistency 2020-10-13 08:53:44 -04:00
Cory LaViska
2ee128a75d Rename var for consistency 2020-10-13 08:52:25 -04:00
Cory LaViska
e61db75263 Fix types 2020-10-13 08:52:09 -04:00
Cory LaViska
4be00e0cda Fix initial transitions; closes #247 2020-10-13 08:26:03 -04:00
Cory LaViska
4d41e09f98 Add visually-hidden mixing 2020-10-13 08:19:26 -04:00
Cory LaViska
646df8aafe Fix broken link 2020-10-12 09:36:25 -04:00
Cory LaViska
c854c986d7 Improve slider size 2020-10-12 09:14:16 -04:00
Cory LaViska
1a67fd9ce7 Improve grid handle size and color 2020-10-12 09:08:16 -04:00
Cory LaViska
fb0ead9603 Update popper; fixes #246 2020-10-12 08:48:50 -04:00
Cory LaViska
02d86709f6 2.0.0-beta.20 2020-10-09 18:11:43 -04:00
Cory LaViska
5dc0c12889 Update version 2020-10-09 18:11:06 -04:00
Cory LaViska
89023a5a4a Update event names to use kebab-case 2020-10-09 17:45:59 -04:00
Cory LaViska
0df547631d Rework events to use kebab-case names 2020-10-09 17:45:16 -04:00
Cory LaViska
e3450fd759 Add integrating with rails to tutorials section 2020-10-08 08:55:50 -04:00
Konnor Rogers
3e33fbb905 Docs/rails-integration (#238)
* docs: add integrations file

* docs: tweak Rails integration

* fix: restore color-picker to original state

* docs: tweak integrations readme
2020-10-08 08:44:26 -04:00
Cory LaViska
4258c8e88c Add ability to customize default icon lib 2020-10-07 10:54:21 -04:00
Cory LaViska
c152f89cce Add sl-icon-library 2020-10-07 09:34:05 -04:00
Cory LaViska
2578215c28 Move icon registration to a utility 2020-10-06 10:09:24 -04:00
Cory LaViska
8da5ae70e3 Add module support to code blocks 2020-10-06 08:17:33 -04:00
Cory LaViska
995744c8ef Fix scroll anchoring in docs 2020-10-06 08:14:07 -04:00
Cory LaViska
a87eb72c59 Fix spellcheck prop 2020-10-06 07:05:10 -04:00
Cory LaViska
4512680b74 Update generated file 2020-10-06 07:04:40 -04:00
Cory LaViska
6c95eddc25 Merge branch 'next' into icon-reg-on-element 2020-10-04 09:09:29 -04:00
Cory LaViska
b9dddbf9fa Fixes #235 2020-10-04 08:38:42 -04:00
Markus Staab
597501ed3f docs: fix typo (#237) 2020-10-04 08:34:46 -04:00
Cory LaViska
dce001ecaf Add spellcheck prop; fixes #233 2020-10-02 15:46:58 -04:00
Cory LaViska
b093ca9c71 Revert "Add spellcheck prop"
This reverts commit 9ce1f9b042.
2020-10-02 15:44:55 -04:00
Cory LaViska
9ce1f9b042 Add spellcheck prop 2020-10-02 15:43:48 -04:00
Cory LaViska
fe1be1c155 Update examples 2020-10-01 13:56:26 -04:00
Cory LaViska
fd21e2aac4 Finish up library reg 2020-10-01 13:39:38 -04:00
Cory LaViska
043bae13a3 Revert example 2020-10-01 13:38:44 -04:00
Cory LaViska
84031833f0 Move changelog to website and remove roadmap 2020-10-01 12:56:58 -04:00
Cory LaViska
b68ac29ab9 Remove log 2020-09-30 12:38:56 -04:00
Cory LaViska
438e597ded Show method signatures 2020-09-30 12:22:15 -04:00
Cory LaViska
b80d6ff97b Fix scroll anchoring bug 2020-09-30 07:57:42 -04:00
Cory LaViska
1b8d913c39 Fix scroll anchoring bug 2020-09-30 07:57:24 -04:00
Cory LaViska
a0fe6e3257 Prototype to register custom libraries on sl-icon 2020-09-29 16:52:16 -04:00
Cory LaViska
493b3eef86 Update changelog 2020-09-28 08:37:00 -04:00
Cory LaViska
e6aedf188c Update comment 2020-09-28 08:19:28 -04:00
Kevin Zolkiewicz
01d484aa91 fix: Improve accuracy of determining activeElement in Dropdown (#224) 2020-09-28 08:16:56 -04:00
Cory LaViska
df7141874d Fixes #227 2020-09-28 07:52:28 -04:00
Cory LaViska
42193557fc Add selection examples to dropdown 2020-09-24 09:17:54 -04:00
Cory LaViska
0f8eb31a07 Add support for dropdowns and non-icons in inputs 2020-09-24 08:58:27 -04:00
Cory LaViska
2b029a6994 Pin Docsify to major version 2020-09-23 14:52:28 -04:00
Cory LaViska
13494f9f32 Fix resize observer types 2020-09-18 15:09:09 -04:00
Cory LaViska
241a7c9acd wtf again vercel 2020-09-18 10:30:57 -04:00
Cory LaViska
751a3f02f3 wtf vercel 2020-09-18 10:22:21 -04:00
Cory LaViska
eb107762d2 Update changelog 2020-09-18 10:01:08 -04:00
Cory LaViska
6a5bca36f5 2.0.0-beta.19 2020-09-18 09:45:09 -04:00
Cory LaViska
48118a908e Update changelog 2020-09-18 09:42:56 -04:00
Cory LaViska
7cee5e8571 Update to Stencil 2.0.3 2020-09-18 09:42:33 -04:00
Cory LaViska
e797f27882 Merge branch 'alert-service' into next 2020-09-18 09:40:46 -04:00
Cory LaViska
be3aae8cb2 Polish off toast 2020-09-18 09:40:21 -04:00
Cory LaViska
af0ade31fd Use toast() method instead of prop 2020-09-17 16:27:11 -04:00
Cory LaViska
e6ed45b1af Docs update 2020-09-16 17:12:52 -04:00
Cory LaViska
5b4424143b meh 2020-09-16 17:00:48 -04:00
Cory LaViska
134a8b26ac Fix stacking bug 2020-09-16 12:42:24 -04:00
Cory LaViska
1065ec0e61 Remove redundant styles 2020-09-16 12:17:08 -04:00
Cory LaViska
5d21c6f2b1 Fixes 2020-09-16 12:06:39 -04:00
Cory LaViska
dbb1a69e67 Add light dom styles; reset duration on mouse move 2020-09-16 11:10:25 -04:00
Cory LaViska
017e6db629 Fix transitions 2020-09-16 10:19:06 -04:00
Cory LaViska
d8b8c8a050 Use toast prop and no light dom 2020-09-16 10:16:08 -04:00
Cory LaViska
ad9de54752 Light DOM variation 2020-09-16 09:34:54 -04:00
Cory LaViska
1546b53d40 Add color example 2020-09-15 08:16:16 -04:00
Cory LaViska
12885bc718 Fix color example 2020-09-15 08:14:56 -04:00
Cory LaViska
1f64cac32a Fix typo 2020-09-15 08:14:43 -04:00
Cory LaViska
b3793752b7 Use spacing token 2020-09-14 17:07:09 -04:00
Cory LaViska
ed393f169e Fixes #210 2020-09-14 09:23:20 -04:00
Cory LaViska
64aae41910 Fixes #208 2020-09-11 10:55:24 -04:00
Cory LaViska
c51c48ef54 Fix buggy custom keyframes demo; closes #204 2020-09-09 21:08:53 -04:00
Cory LaViska
d8fc0464bb Refactor clear logic in input 2020-09-09 16:19:48 -04:00
Cory LaViska
6a731ca015 Prevent mouse events from bubbling up in buttons 2020-09-08 08:27:07 -04:00
Cory LaViska
4bf67c839a Export inputs parts in sl-select; fixes #206 2020-09-08 07:39:46 -04:00
Cory LaViska
66cb7bb238 Fix changelog 2020-09-04 17:59:40 -04:00
Cory LaViska
de0554c5af 2.0.0-beta.18 2020-09-04 17:39:25 -04:00
Cory LaViska
606a4cf93f Update version 2020-09-04 17:38:23 -04:00
Cory LaViska
83e4235ccb Add touch support to demo resizer 2020-09-04 17:37:50 -04:00
Cory LaViska
5ae49175af Fix typo 2020-09-04 17:11:25 -04:00
Cory LaViska
a8f040f3f0 Fix placements 2020-09-04 16:18:00 -04:00
Cory LaViska
662e76ce34 Remove incorrect validation examples 2020-09-04 15:06:13 -04:00
Cory LaViska
56b64940ca Add support for form submission and validation in color picker 2020-09-04 10:18:46 -04:00
Cory LaViska
9285dd5926 Remove -webkit-appearance property 2020-09-04 10:16:48 -04:00
Cory LaViska
fbd3a67dac Fix onAfterShow callback 2020-09-04 10:15:35 -04:00
Cory LaViska
551f57aa9a Fix color picker form submit bug 2020-09-04 08:57:34 -04:00
Cory LaViska
b51978b1a6 Fix duplicate slBlur/slFocus in select; closes #200 2020-09-04 08:02:39 -04:00
Cory LaViska
84d4421575 Improve keyboard logic 2020-09-03 17:44:52 -04:00
Cory LaViska
efc4dad817 Update docs 2020-09-03 13:05:43 -04:00
Cory LaViska
0a5c4da2d1 Fix menu focus bug 2020-09-03 12:53:04 -04:00
Cory LaViska
8b4507cf60 Fix disabled cursor in select 2020-09-03 10:25:14 -04:00
Cory LaViska
3568378975 Simplify example 2020-09-02 17:58:21 -04:00
Cory LaViska
72b0c46d2f Fix animation bug and refactor 2020-09-02 17:45:59 -04:00
Cory LaViska
6529200dda Return '' for slots that are null or not loaded 2020-09-02 17:23:33 -04:00
Cory LaViska
2aa0f83e6a Fix typo in comment 2020-09-02 16:59:20 -04:00
Cory LaViska
8b7b7ee319 Update changelog 2020-09-02 16:59:05 -04:00
Cory LaViska
41b847586a Update entry points for Stencil 2.0 2020-09-02 16:58:26 -04:00
Cory LaViska
0c4beb3608 Use copy cursors 2020-09-02 07:51:19 -04:00
Cory LaViska
215ea51a26 Add responsive embed utility component 2020-08-31 16:47:31 -04:00
Cory LaViska
e361a5cad7 Prevent iframes from stealing events while dragging 2020-08-31 16:46:22 -04:00
Cory LaViska
e055fe9027 Update to Stencil 2.0 2020-08-31 16:45:43 -04:00
Cory LaViska
72d5a359a6 2.0.0-beta.17 2020-08-31 08:50:48 -04:00
Cory LaViska
f36f0d7fb2 Update changelog 2020-08-31 08:49:19 -04:00
Cory LaViska
2cf2f63c86 Use directional cursor 2020-08-31 08:46:41 -04:00
Cory LaViska
a5417c16a7 Update icons info 2020-08-31 08:28:31 -04:00
Cory LaViska
91196f3577 Update docs 2020-08-31 07:41:58 -04:00
Cory LaViska
0d521167b0 Update docs 2020-08-31 07:38:44 -04:00
Cory LaViska
fa5b4e5cbd Fix typo 2020-08-31 07:18:23 -04:00
Cory LaViska
9ad226924c Merge branch 'input-validation' into next 2020-08-31 07:08:24 -04:00
Cory LaViska
b1f1d0de12 Update generated file 2020-08-31 07:06:49 -04:00
Marvin Tunji-ola
36ac492651 Update: changed alert class name from Tab to Alert (#196) 2020-08-31 07:06:02 -04:00
Cory LaViska
01237ee3ef Clarify the active prop 2020-08-29 20:01:16 -04:00
Chris Haynes
bb323b9e15 Run tests in parallel
Switch back to running tests in parallel as the tests are now more reliable under load.
2020-08-29 23:40:03 +01:00
Chris Haynes
049f8a6747 Add e2e tests for slColorPicker 2020-08-29 23:39:07 +01:00
Chris Haynes
b7e10cc115 Use more reliable wait for slAfter* events
Instead of waiting for `transitionend` events which can be brittle, instead wait for the event itself to happen before testing for it.
2020-08-29 23:38:36 +01:00
Cory LaViska
e51490b71c Update + optimize meta images 2020-08-29 13:23:11 -04:00
Cory LaViska
918b11f558 Improve documentation 2020-08-29 12:52:13 -04:00
Cory LaViska
a27e33463b Update docs 2020-08-29 11:53:24 -04:00
Cory LaViska
03ca66eba3 Improve faux readonly behavior 2020-08-29 11:26:14 -04:00
Cory LaViska
486521cf77 Update docs/changelog 2020-08-29 10:39:53 -04:00
Cory LaViska
08bd5fe146 Add novalidate 2020-08-29 10:39:18 -04:00
Cory LaViska
73b54242d2 Merge branch 'next' into input-validation 2020-08-29 10:21:44 -04:00
Cory LaViska
11325dddae Update bootstrap icons 2020-08-29 10:15:06 -04:00
Chris Haynes
d6cca3e927 Run tests in series
Running tests in parallel can lead to timeout errors - presumably because the Puppeteer Chrome instances are heavyweight and causing slowdowns?
2020-08-28 23:57:30 +01:00
Chris Haynes
01804e83b6 Remove only left inadvertently in tests 2020-08-28 23:44:26 +01:00
Chris Haynes
4ae563518f Add value property checks for Input/Textarea 2020-08-28 23:41:57 +01:00
Chris Haynes
74dc291499 Add e2e tests for slSelect 2020-08-28 23:36:53 +01:00
Chris Haynes
805e6ce411 Add e2e tests for slTag 2020-08-28 23:19:30 +01:00
Chris Haynes
0f93d84ead Add e2e tests for slTextarea 2020-08-28 23:16:04 +01:00
Chris Haynes
c8ca446eb0 slRadio - add additional tests for checked property 2020-08-28 23:12:37 +01:00
Chris Haynes
7c82d46576 slCheckbox - add additional tests for checked property 2020-08-28 23:11:30 +01:00
Chris Haynes
0bd7a1b2b4 Add e2e tests for slSwitch 2020-08-28 23:10:38 +01:00
Chris Haynes
d144bad3f9 Add e2e tests for slRating 2020-08-28 23:02:10 +01:00
Chris Haynes
abdd33c6ef Add e2e tests for slRange 2020-08-28 23:01:09 +01:00
Cory LaViska
61689a63a3 Update changelog 2020-08-28 17:39:56 -04:00
Cory LaViska
ba7242367a Remove slValid/slInvalid events 2020-08-28 17:37:36 -04:00
Cory LaViska
6e1ccdeb9a Update changelog 2020-08-28 17:34:58 -04:00
Chris Haynes
3a2b68f098 Add e2e tests for slRadio 2020-08-28 22:30:49 +01:00
Cory LaViska
d14944aba6 Update changelog 2020-08-28 17:29:07 -04:00
Chris Haynes
d6263b5466 Add e2e tests for slMenuItem 2020-08-28 22:27:14 +01:00
Cory LaViska
bc92981c16 Fix select validation 2020-08-28 17:24:23 -04:00
Chris Haynes
1483bc48ec Add e2e tests for slMenu 2020-08-28 22:10:21 +01:00
Cory LaViska
9612a77c7e Make checkboxes show validation message 2020-08-28 16:55:27 -04:00
Cory LaViska
484e2fe875 Added form control info 2020-08-28 16:53:39 -04:00
Cory LaViska
50775daec8 Make setCustomValidity a method; add report/set to all form controls 2020-08-28 16:50:18 -04:00
Cory LaViska
7c76fb3813 Rework input validation 2020-08-28 16:14:39 -04:00
Chris Haynes
d6e19f8dbb Fix slFocus/slBlur transposition 2020-08-28 21:05:54 +01:00
Chris Haynes
4021f333fa Add e2e tests for slInput 2020-08-28 20:56:04 +01:00
Chris Haynes
fd7ef71438 Add e2e tests for slForm 2020-08-28 20:56:04 +01:00
Chris Haynes
ee77675f54 Replace flakey wait timeouts
Instead wait for `transitionend` on appropriate elements
2020-08-28 20:56:04 +01:00
Chris Haynes
a9de1189ef Add e2e tests for slDropdown 2020-08-28 20:56:04 +01:00
Chris Haynes
b7848eb360 Add e2e tests for slDetails 2020-08-28 20:56:04 +01:00
Chris Haynes
6e99d517ab Add e2e tests for slCheckbox 2020-08-28 20:56:04 +01:00
Chris Haynes
8b0a51337f Add e2e tests for slButton 2020-08-28 20:56:04 +01:00
Chris Haynes
2d6c220ae2 Add e2e tests for slAlert 2020-08-28 20:56:04 +01:00
Chris Haynes
1eb991fe3a Add e2e tests for slDrawer 2020-08-28 20:56:03 +01:00
Chris Haynes
a9ce30f445 Add e2e tests for slDialog 2020-08-28 20:56:03 +01:00
Chris Haynes
5218a08e00 Add e2e tests for slTabGroup 2020-08-28 20:56:03 +01:00
Chris Haynes
b77c7f5a43 Adds stencil test dependencies 2020-08-28 20:56:03 +01:00
Cory LaViska
05f02bb03b Update changelog 2020-08-28 07:19:54 -04:00
Cory LaViska
e16ad458ee Remove return value since there isn't one 2020-08-28 06:53:22 -04:00
Chris Haynes
f0ba06e6ec Fixes #188 - update value after setRangeText call (#189)
* Fixes #188 - update value after setRangeText call

* Apply setRangeText fix to textarea

* Update setRangeFix to check for changed value
2020-08-28 06:51:48 -04:00
Cory LaViska
6b9a07eab8 Fix slot listeners 2020-08-27 17:14:47 -04:00
Cory LaViska
f4c2611575 Fix role/aria 2020-08-27 16:51:31 -04:00
Cory LaViska
63ef5dcf57 Update changelog 2020-08-27 16:45:10 -04:00
Cory LaViska
8e94f9fa9e Optimize hasSlot selector 2020-08-27 16:30:45 -04:00
Cory LaViska
83825d899d Refactor slotchange listeners 2020-08-27 15:54:06 -04:00
Cory LaViska
6b46a557f4 Sounds better 2020-08-27 14:13:44 -04:00
Cory LaViska
f0e0535120 Update contribution guidelines 2020-08-27 14:09:10 -04:00
Cory LaViska
6adca7eed1 Fixed value = null error; closes #187 2020-08-27 12:23:24 -04:00
Cory LaViska
8a4ee01f8a Update changelog 2020-08-27 09:16:49 -04:00
Cory LaViska
82b41ebaed Fix select options positioning; closes #184 2020-08-27 09:16:34 -04:00
Cory LaViska
2aca25c476 Toggle menu when clicking a tag 2020-08-27 08:20:36 -04:00
Cory LaViska
f438393db0 Fix cursor 2020-08-27 08:19:31 -04:00
Cory LaViska
90c5e77b1d Make overflowing content more sane 2020-08-27 08:19:05 -04:00
Cory LaViska
7cdfaed5f2 2.0.0-beta.16 2020-08-26 09:11:57 -04:00
Cory LaViska
9ad1963ebc Add keyboard support to resizer 2020-08-26 09:09:04 -04:00
Cory LaViska
4b0008b0a7 Fix input color tokens bug 2020-08-26 08:30:50 -04:00
Cory LaViska
9d194a17f4 Fix tooltip custom properties 2020-08-26 07:09:01 -04:00
Cory LaViska
c54ef43534 More explicit selectors 2020-08-26 07:08:41 -04:00
Cory LaViska
c9a2aabd1f Rename positioner 2020-08-26 06:47:27 -04:00
Cory LaViska
e511534399 Fix border color for dark mode 2020-08-26 06:47:14 -04:00
Cory LaViska
b78f5990f6 Use positioner for tooltip 2020-08-25 18:01:23 -04:00
Cory LaViska
8f2efa848b Separate position and transition 2020-08-25 17:51:52 -04:00
Cory LaViska
a69063934c Add transitionElement option 2020-08-25 17:51:32 -04:00
Cory LaViska
b8f52e48ec Add hoist prop; fixes #179 2020-08-25 17:07:28 -04:00
Cory LaViska
7d5aac4bc8 Add clearable and required props to select; fixes #182 2020-08-25 16:25:25 -04:00
Cory LaViska
e169c937df Add slClear event to input 2020-08-25 16:24:33 -04:00
Cory LaViska
de1daad04e Reorder examples 2020-08-25 16:23:33 -04:00
Cory LaViska
cd0d01f5e5 Add required prop to select 2020-08-25 09:30:28 -04:00
Cory LaViska
26d04a9b2e Add format-bytes utility component 2020-08-25 09:20:13 -04:00
Cory LaViska
ac31a16b8e Fix aria state 2020-08-24 12:11:55 -04:00
Cory LaViska
35d5e7950b Add vue data binding tip 2020-08-24 11:45:17 -04:00
Cory LaViska
04234859cb Fix switch demo 2020-08-24 10:02:45 -04:00
Cory LaViska
39ee5f1f69 2.0.0-beta.15 2020-08-24 09:53:55 -04:00
Cory LaViska
7749ce152f Revert version 2020-08-24 09:53:15 -04:00
Cory LaViska
66ec4173b8 2.0.0-beta.15 2020-08-24 09:50:45 -04:00
Cory LaViska
6f63b4796e Update Twitter card 2020-08-24 09:46:16 -04:00
Cory LaViska
2039528b6f Update changelog 2020-08-24 09:36:04 -04:00
Cory LaViska
ee42170f7b Add slot docs 2020-08-24 09:32:39 -04:00
Cory LaViska
b7da427477 Use unsplash images 2020-08-24 09:29:40 -04:00
Cory LaViska
3b6fe57909 Refactor styles 2020-08-24 09:23:02 -04:00
Cory LaViska
2349bc8074 Use scrollbar role 2020-08-24 09:22:52 -04:00
Cory LaViska
4470f73147 Update examples 2020-08-24 09:22:34 -04:00
Cory LaViska
175d85a96d Add image comparer 2020-08-21 17:27:11 -04:00
Cory LaViska
492dac47ab Update pill example 2020-08-21 16:59:48 -04:00
Cory LaViska
d0f4478f94 Remove hover/keyboard conflict logic 2020-08-21 16:59:36 -04:00
Cory LaViska
d9c5d270f2 Fix select bugs 2020-08-21 16:58:02 -04:00
Cory LaViska
8da9dd7873 Make TypeScript 4 happy 2020-08-21 06:50:31 -04:00
Cory LaViska
d949eba957 Add missing part docs 2020-08-21 06:35:39 -04:00
Cory LaViska
04ac34382e Move collections together 2020-08-20 12:03:13 -04:00
Cory LaViska
20926fbaa1 Update changelog 2020-08-20 09:13:06 -04:00
Cory LaViska
21889924e7 Fix aria-labelledby attributes 2020-08-20 09:12:13 -04:00
Cory LaViska
ee41a71ccd Expose switch custom props and fix width bug 2020-08-20 09:09:23 -04:00
Cory LaViska
c6ae475d42 Update changelog 2020-08-20 08:58:21 -04:00
Cory LaViska
dd9b955113 Fix webkit autocomplete colors 2020-08-20 08:57:13 -04:00
Cory LaViska
eed5a61300 Remove color example 2020-08-20 08:45:33 -04:00
Cory LaViska
7183ddc172 Fix border color in example 2020-08-20 08:33:30 -04:00
Cory LaViska
4221ad70c9 Fix menu item color when disabled + dark 2020-08-20 08:33:18 -04:00
Cory LaViska
8aa598ee92 Fix border color in dark mode 2020-08-20 08:27:00 -04:00
Cory LaViska
c71bbb4384 Update value on change 2020-08-20 08:25:52 -04:00
Cory LaViska
794f2fe5a0 Add discord link 2020-08-20 08:25:01 -04:00
Cory LaViska
85952f296c Improve code highlighter contrast in dark mode 2020-08-19 08:56:31 -04:00
Cory LaViska
956129950c 2.0.0-beta.14 2020-08-18 17:44:53 -04:00
Cory LaViska
9fc00f7802 Revert version 2020-08-18 17:43:44 -04:00
Cory LaViska
4a7ae4e388 2.0.0-beta.14 2020-08-18 17:43:06 -04:00
Cory LaViska
406696f4ff Revert version 2020-08-18 17:42:30 -04:00
Cory LaViska
f714d57898 2.0.0-beta.15 2020-08-18 17:39:32 -04:00
Cory LaViska
1fe5c6b4ec Overwrite directory 2020-08-18 17:39:01 -04:00
Cory LaViska
94f2327f91 2.0.0-beta.14 2020-08-18 17:38:01 -04:00
Cory LaViska
0502ad3f23 Remove tooltip 2020-08-18 17:35:50 -04:00
Cory LaViska
9cceb8d3e2 Update changelog 2020-08-18 17:31:43 -04:00
Cory LaViska
a64d25cfa4 Remove unused comment 2020-08-18 17:31:31 -04:00
Cory LaViska
e6198c853e Copy themes to docs dist 2020-08-18 17:30:58 -04:00
Cory LaViska
48cfeaa6b2 Update to Stencil 1.17.3 2020-08-18 17:17:06 -04:00
Cory LaViska
9fdb88a319 Update readme 2020-08-18 17:13:20 -04:00
Cory LaViska
64185c407e Update theme docs 2020-08-18 17:10:23 -04:00
Cory LaViska
e0f8305ee2 Dark theme improvements 2020-08-18 17:10:09 -04:00
Cory LaViska
0a0ada994c Update content 2020-08-18 17:09:50 -04:00
Cory LaViska
15ca33b55b Update content 2020-08-18 17:09:25 -04:00
Cory LaViska
c8cbfa3253 Remove panel part (not breaking) 2020-08-18 17:09:06 -04:00
Cory LaViska
92e58b9657 Remove menu and panel parts (not breaking); add tag part 2020-08-18 17:08:47 -04:00
Cory LaViska
0ebdcbe220 Adjust menu label color 2020-08-18 17:08:00 -04:00
Cory LaViska
f3b0e3ccc9 Remove default theme class
We can't scope the default theme like we can other themes because they use ::part and have a higher specificity, so this isn't very useful.
2020-08-18 17:07:39 -04:00
Cory LaViska
76e5ed1d93 Use border radius token for inputs 2020-08-18 17:06:48 -04:00
Cory LaViska
ae5af1edb7 Add panel tokens 2020-08-18 17:05:46 -04:00
Cory LaViska
2f56622b42 Fix tip/warning icon color 2020-08-18 17:03:59 -04:00
Cory LaViska
386a247bc5 Add tooltip to theme selector 2020-08-18 17:03:42 -04:00
Cory LaViska
165aae1c8a Expose themes 2020-08-18 09:45:34 -04:00
Cory LaViska
761a2e7eee Serve and watch themes dir 2020-08-18 09:42:57 -04:00
Cory LaViska
2b776661ca Move dark theme to themes dir 2020-08-18 09:41:02 -04:00
Cory LaViska
e74eb8d907 Fix dark comments 2020-08-18 09:40:28 -04:00
Cory LaViska
c49fbf3587 Cleanup selectors 2020-08-17 16:52:52 -04:00
Cory LaViska
186e4567f2 Merge branch 'next' into theme-dark 2020-08-17 16:36:32 -04:00
Cory LaViska
a70d395502 Expose custom elements bundle in the root 2020-08-17 16:36:05 -04:00
Cory LaViska
5c4f3fa2a4 Make mobile toggle larger 2020-08-17 10:02:54 -04:00
Cory LaViska
da9ffb70fc Update theme docs 2020-08-17 09:59:38 -04:00
Cory LaViska
c6f081c399 Finish up dark theme and split files 2020-08-17 08:23:27 -04:00
Cory LaViska
d45dc5144e Export parts for color picker 2020-08-17 08:23:06 -04:00
Cory LaViska
474ef6182f Export parts for select 2020-08-17 08:22:53 -04:00
Cory LaViska
bcfd8f1d19 Fix code block bgs 2020-08-17 08:22:01 -04:00
Cory LaViska
661a84941e Finish initial dark mode component styles 2020-08-16 11:28:23 -04:00
Cory LaViska
c0ab6abc83 Update 2020-08-16 11:27:47 -04:00
Cory LaViska
6d09a43fbf Reflect tag props 2020-08-16 11:27:18 -04:00
Cory LaViska
90a309d006 Refactor property name 2020-08-16 11:27:06 -04:00
Cory LaViska
88bd79fa1b Remove default color prop from progress ring 2020-08-16 11:26:52 -04:00
Cory LaViska
a566e6b48d Reflect menu item props 2020-08-16 11:26:31 -04:00
Cory LaViska
3130ea1c39 Add --color to menu divider 2020-08-16 11:26:11 -04:00
Cory LaViska
2f15b782f8 Move bg color styles from menu item to menu 2020-08-16 11:25:58 -04:00
Cory LaViska
d658aa5fed Add --tabs-border-color to tab-group 2020-08-16 11:25:23 -04:00
Cory LaViska
229fa437e0 Reflect tab props 2020-08-16 11:25:11 -04:00
Cory LaViska
b402f2f2ab Add --track-color to range 2020-08-16 11:24:58 -04:00
Cory LaViska
2ffc1de1b6 Reflect icon button props 2020-08-16 11:24:43 -04:00
Cory LaViska
dab9b8a1f5 Fix bug where radio dot was always technically visible 2020-08-16 10:58:15 -04:00
Cory LaViska
15f0662e77 Fix bug where progress bar had the wrong part name 2020-08-16 10:54:11 -04:00
Cory LaViska
19934bbd15 Revert "Revert "Revert "Revert "Initial dark theme (WIP)""""
This reverts commit 389b9248db.
2020-08-14 17:56:40 -04:00
Cory LaViska
389b9248db Revert "Revert "Revert "Initial dark theme (WIP)"""
This reverts commit 76e86922f0.
2020-08-14 17:55:44 -04:00
Cory LaViska
76e86922f0 Revert "Revert "Initial dark theme (WIP)""
This reverts commit 4e1abbc885.
2020-08-14 17:43:29 -04:00
Cory LaViska
4e1abbc885 Revert "Initial dark theme (WIP)"
This reverts commit 787735cec7.
2020-08-14 17:38:35 -04:00
Cory LaViska
d4ff32efba Revert "Make prettier happy"
This reverts commit 35074461b8.
2020-08-14 17:38:27 -04:00
Cory LaViska
35074461b8 Make prettier happy 2020-08-14 17:31:46 -04:00
Cory LaViska
787735cec7 Initial dark theme (WIP) 2020-08-14 17:31:21 -04:00
Cory LaViska
573552b457 Rework show/hide logic; #fixes 170 2020-08-13 10:29:31 -04:00
Cory LaViska
fba34699c6 Update changelog 2020-08-13 07:44:46 -04:00
Cory LaViska
b1a93d73c8 Prevent duplicate show/hide events; fixes #170 2020-08-13 07:43:45 -04:00
Cory LaViska
2f9290fafe Fixes Safari dialog resize bug; closes #171 2020-08-13 07:24:18 -04:00
Cory LaViska
e8159bde53 2.0.0-beta.13 2020-08-12 08:55:48 -04:00
Cory LaViska
c3cf3f8ba2 Add examples 2020-08-12 08:53:11 -04:00
Cory LaViska
cc7501e530 Allow type to select to accept symbols 2020-08-12 08:21:39 -04:00
Cory LaViska
a26df1242c Update changelog 2020-08-12 07:42:01 -04:00
Cory LaViska
6c62de9e36 Update attribution 2020-08-12 07:40:19 -04:00
Cory LaViska
965ce6911a Update changelog 2020-08-12 07:36:25 -04:00
Cory LaViska
e64a23cdfc Set initial playback rate 2020-08-12 07:35:00 -04:00
Cory LaViska
3567b3f6f4 Set default duration 2020-08-12 07:25:16 -04:00
Cory LaViska
945630e235 Prevent Safari from borking scrolling for menus in dropdowns 2020-08-12 07:02:43 -04:00
Cory LaViska
63f6cfddf6 Animations 2020-08-11 18:47:02 -04:00
Cory LaViska
afc5e292c3 Rewrite animation component from scratch 2020-08-11 09:32:10 -04:00
Cory LaViska
8387edb080 Remove button links plugin from docs 2020-08-11 06:32:40 -04:00
Cory LaViska
f2a33ab070 Update; not gonna fork 2020-08-10 10:45:46 -04:00
Cory LaViska
9b5ac44934 Initial fork of animatable-component 2020-08-10 10:04:25 -04:00
Cory LaViska
9391ea876a Fix examples 2020-08-10 07:50:16 -04:00
Cory LaViska
2d23bda88b Add shields 2020-08-10 07:34:16 -04:00
Cory LaViska
9e3198c38a Revert examples 2020-08-08 16:17:22 -04:00
Cory LaViska
56b669da0d Update changelog 2020-08-08 16:11:41 -04:00
Cory LaViska
0a436cb76c Update changelog 2020-08-08 16:10:01 -04:00
Cory LaViska
6c16eb9a11 Add slActivate/slDeactivate events to menu item 2020-08-08 15:45:32 -04:00
Cory LaViska
be44db8e35 Move scrollIntoView logic from menu to dropdown 2020-08-08 15:26:21 -04:00
Cory LaViska
251e3059a0 Move scrolling from menu to dropdown panel 2020-08-08 15:00:12 -04:00
Cory LaViska
d70908ef8d Fix button group tooltips in Safari 2020-08-07 16:43:40 -04:00
Cory LaViska
f5fcfb2faf Fix whitespace in example 2020-08-07 16:31:47 -04:00
Cory LaViska
bc5ea9cf00 Fix link button type bug 2020-08-07 16:18:15 -04:00
Cory LaViska
e619963356 2.0.0-beta.12 2020-08-07 16:03:18 -04:00
Cory LaViska
12581ca76b Add support for link buttons; closes #165 2020-08-07 15:42:55 -04:00
Cory LaViska
883d6974e9 Add kbd styles 2020-08-07 15:39:39 -04:00
Cory LaViska
92e3cd46c5 Make sidebar spacing more consistent 2020-08-07 08:37:46 -04:00
Cory LaViska
31caeb7bed Add CSS var + CSS part section 2020-08-07 07:44:00 -04:00
Cory LaViska
e96705a6ae Fix typo 2020-08-06 13:59:31 -04:00
Cory LaViska
407f66dc2b Update changelog 2020-08-06 12:30:19 -04:00
Nathan Berks
592977b7b8 Update index.ts component export ref (#163)
Co-authored-by: nathanb21 <nathan.berks@nanoporetech.com>
2020-08-06 12:25:44 -04:00
Cory LaViska
68f08b04bb Fix button width in Safari 2020-08-06 12:13:11 -04:00
Cory LaViska
a62370d590 2.0.0-beta.11 2020-08-06 09:17:35 -04:00
Cory LaViska
7574c0e840 Remove console.log 2020-08-06 09:13:45 -04:00
Cory LaViska
3a508ac1e2 Update changelog 2020-08-06 09:09:56 -04:00
Cory LaViska
2b2a37bc3f Add button group component 2020-08-06 09:07:24 -04:00
Cory LaViska
767decf6c6 Fix icon button alignment 2020-08-06 09:05:50 -04:00
Cory LaViska
80fa1cea83 Use disconnectedCallback instead of componentDidUnload; fixes #161 2020-08-06 06:56:29 -04:00
Nathan Berks
60befc34d3 Fixes #158 - Add missing unobserve on unload of sl-details component (#159)
* Fix missing unobserve on unload

Co-authored-by: Nathan Berks <nathan.berks@nanoporetech.com>
2020-08-06 06:49:49 -04:00
Cory LaViska
d5eed12177 Fix bug where focusVisible observer wasn't removed from details 2020-08-05 14:54:48 -04:00
Cory LaViska
b27fc01118 Fixes #160 2020-08-05 13:56:47 -04:00
Cory LaViska
b15a12d4e1 Fix details initial height when open; closes #160 2020-08-05 13:45:39 -04:00
Cory LaViska
e5a38c27af Update skeleton example 2020-08-04 15:37:36 -04:00
Cory LaViska
287badc529 Update roadmap 2020-08-04 12:52:39 -04:00
Cory LaViska
dfc2990e79 2.0.0-beta.10 2020-08-03 17:08:03 -04:00
Cory LaViska
bc154f2506 Add community page 2020-08-03 17:05:47 -04:00
Cory LaViska
c77c0716d3 Add button links plugin 2020-08-03 17:05:32 -04:00
Cory LaViska
6a3b2c995d Update docs 2020-08-03 12:54:47 -04:00
Cory LaViska
1e65163983 Move methods 2020-08-03 07:40:53 -04:00
Cory LaViska
9974771185 Fixed bug where tab group wasn't scrollable by mouse 2020-08-03 07:40:02 -04:00
Cory LaViska
41ff07b965 Add header part to details; fixes #150 2020-08-02 06:54:17 -04:00
Chris Haynes
b51871aca3 Tab Group - set active tab when element is visible (#154)
Another great catch. Thanks!
2020-08-02 06:49:47 -04:00
Cory LaViska
887bfb258b Merge branch 'lamplightdev-fix/tabgroup-mutation-observer' into next 2020-08-02 06:47:05 -04:00
Chris Haynes
92fdc551d8 Merge branch 'fix/tabgroup-mutation-observer' of https://github.com/lamplightdev/shoelace into fix/tabgroup-mutation-observer
* 'fix/tabgroup-mutation-observer' of https://github.com/lamplightdev/shoelace:
  Fix typo in aria attribute
  Fixes #148 - prevents recursive calls to observer
2020-08-01 22:43:17 +01:00
Chris Haynes
d09c4f06a7 Fix typo in aria attribute 2020-08-01 22:40:40 +01:00
Chris Haynes
8f0c1eb339 Fixes #148 - prevents recursive calls to observer
Uses a block list for the attributes that shouldn't trigger the observer. It may be better to use an allow list since the observer is still called unnecessarily for e.g. `style` attribute changes.
2020-08-01 20:34:07 +01:00
Chris Haynes
4789399170 Fixes #148 - prevents recursive calls to observer
Uses a block list for the attributes that shouldn't trigger the observer. It may be better to use an allow list since the observer is still called unnecessarily for e.g. `style` attribute changes.
2020-07-30 22:27:43 +01:00
Cory LaViska
c1300ea3d6 Show star count 2020-07-29 10:37:22 -04:00
Cory LaViska
39992b4432 Update readme 2020-07-29 08:11:54 -04:00
Cory LaViska
338a6f7239 Remove npx 2020-07-29 08:09:21 -04:00
Cory LaViska
1cc074f549 Add code completion instructions; fixes #144 2020-07-29 08:05:50 -04:00
Cory LaViska
7b6f59efb6 Add custom-elements.json for vscode 2020-07-29 07:37:32 -04:00
Cory LaViska
354cacfacb Update changelog 2020-07-29 07:17:20 -04:00
Chris Haynes
4e3934eb28 Ensures there are no id clashes (#146)
Ensures there are no id clashes by renaming the internal id property to componentId
2020-07-29 07:15:47 -04:00
Cory LaViska
a64f47445a 2.0.0-beta.9 2020-07-28 08:50:52 -04:00
Cory LaViska
24893938ce Update changelog 2020-07-28 08:46:18 -04:00
Cory LaViska
766a1505f7 Update to Stencil 17.1 2020-07-28 08:46:08 -04:00
Cory LaViska
f02a09b697 Fix comment 2020-07-28 08:41:55 -04:00
Cory LaViska
919d75c022 First version of skeleton 2020-07-28 08:41:45 -04:00
Cory LaViska
6ad0d676ef Merge branch 'next' into skeleton 2020-07-28 05:58:32 -04:00
Cory LaViska
e75ab46665 Remove hidden prop from example 2020-07-28 05:58:11 -04:00
Cory LaViska
c32581678a Super early implementation 2020-07-27 16:20:15 -04:00
Cory LaViska
5d9608b6bc Update changelog 2020-07-27 07:50:50 -04:00
Cory LaViska
b4dfae2a79 Fix bug where color picker wouldn't parse uppercase values 2020-07-27 07:36:17 -04:00
Cory LaViska
1bfbd665fa Add pulse prop to badge 2020-07-27 07:32:17 -04:00
Cory LaViska
6aa16801bd Update changelog 2020-07-24 17:00:38 -04:00
Cory LaViska
dab39c24f9 Update card example 2020-07-24 16:57:54 -04:00
Cory LaViska
96f32122c0 Add icon button 2020-07-24 16:57:38 -04:00
Cory LaViska
79b84cc47e Fix bug where pressing enter on a tag would open the control 2020-07-24 16:57:19 -04:00
Cory LaViska
40976e58fa Update changelog 2020-07-24 15:29:00 -04:00
Cory LaViska
bd07f16348 Fix focus bug; move method into correct place 2020-07-24 15:28:14 -04:00
Cory LaViska
ab82ceaa2e Fix bash highlighters 2020-07-24 14:15:32 -04:00
Cory LaViska
23d749c1fd Fix comment 2020-07-24 11:06:25 -04:00
Cory LaViska
5083bfff0b Update changelog 2020-07-24 10:44:35 -04:00
Cory LaViska
7bcc9c9886 Update stencil to 1.17 2020-07-24 10:44:11 -04:00
Cory LaViska
127dabc596 Update changelog 2020-07-24 10:42:55 -04:00
Cory LaViska
4ec2a34718 Fix type-to-select behavior; add typeToSelect method to menu 2020-07-24 10:41:52 -04:00
Cory LaViska
46c402c126 Switch to jsdelivr for better performance 2020-07-24 09:41:47 -04:00
Cory LaViska
dbbeda9663 Update changelog 2020-07-24 09:34:14 -04:00
Cory LaViska
f32b54cae3 Make dropdowns give focus back to the trigger when closing 2020-07-24 09:28:36 -04:00
Cory LaViska
91a023e564 Remove unused method 2020-07-24 09:27:11 -04:00
Cory LaViska
3e0f174052 Prevent text selection when select is focused 2020-07-24 09:25:41 -04:00
Cory LaViska
89cce4bbb8 Close select when tabbing 2020-07-24 09:25:09 -04:00
Cory LaViska
caef94339b Remove benign properties 2020-07-24 08:44:31 -04:00
Cory LaViska
288f58c1ee Update changelog 2020-07-24 08:38:39 -04:00
Cory LaViska
a220b694ef Make footer slot existence automatic (dialog, drawer) 2020-07-24 08:38:00 -04:00
Cory LaViska
60e8e4579a Remove unused prop 2020-07-24 08:24:33 -04:00
Cory LaViska
0492182fac Update changelog 2020-07-23 18:01:13 -04:00
Cory LaViska
308d68bcb4 Fix cursor when hovering over select 2020-07-23 18:00:43 -04:00
Cory LaViska
5cf9fb6e7e Fix typo 2020-07-23 17:57:24 -04:00
Cory LaViska
fc7b88a8d5 2.0.0-beta.8 2020-07-23 17:41:26 -04:00
Cory LaViska
9565a7de6d Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2020-07-23 17:30:21 -04:00
Cory LaViska
3ae2efd6db Update changelog 2020-07-23 17:30:13 -04:00
Cory LaViska
37303fe6f6 Update bundler examples 2020-07-23 17:29:50 -04:00
Chris Haynes
0328854285 Fixes #135 - uses the composedPath() array to find the closest matching elements the event was triggered on (#136)
composedPath() is preferred over closest() since it pierces shadow DOM boundaries
2020-07-23 17:12:05 -04:00
Cory LaViska
81816fba56 Add twitter card metadata 2020-07-23 15:30:31 -04:00
Cory LaViska
53e34b7967 Update analytics 2020-07-23 13:34:24 -04:00
Cory LaViska
a2906e9d6a Upgrade to stencil/core@next for custom elements bundle 2020-07-23 08:37:44 -04:00
Cory LaViska
30c7424562 Make stencil a dev dep 2020-07-23 08:36:06 -04:00
Cory LaViska
b8a6b62796 Add note about accessibility 2020-07-23 07:32:42 -04:00
Cory LaViska
b967e8912e Add changelog section 2020-07-23 06:50:09 -04:00
Cory LaViska
e8437e6fbb Update versioning info 2020-07-23 06:47:12 -04:00
Cory LaViska
9841cf8aee Update changelog 2020-07-22 17:27:50 -04:00
Cory LaViska
e3f5f66557 Merge branch 'current' into next 2020-07-22 17:21:03 -04:00
Cory LaViska
58376d8973 Update master branch to current 2020-07-22 17:20:45 -04:00
Cory LaViska
69d3daff4a Merge branch 'card' into next 2020-07-22 17:13:53 -04:00
Cory LaViska
db0a88c276 Update custom elements docs 2020-07-22 17:13:38 -04:00
Cory LaViska
e1b0d67df5 Use Stencil 1.17.0-0 for custom elements build 2020-07-22 17:13:21 -04:00
Cory LaViska
66c3de9c3b Add card component 2020-07-22 16:02:49 -04:00
Cory LaViska
905152a412 Add hasSlot utility 2020-07-22 16:02:32 -04:00
Cory LaViska
8177ce2a4a Update badge status 2020-07-22 16:02:20 -04:00
Cory LaViska
4234292ec4 Remove comment 2020-07-22 16:02:07 -04:00
Cory LaViska
3c1ad8e0dc Fix rating display for easier alignment 2020-07-22 11:49:51 -04:00
Cory LaViska
dd456536f5 Remove zoom image docs plugin 2020-07-22 07:36:25 -04:00
Cory LaViska
f2a7ab3f40 Use design token 2020-07-22 07:20:11 -04:00
Cory LaViska
d6c8afb9bc Fix range tooltip on iOS; closes #110 2020-07-22 07:12:08 -04:00
Cory LaViska
c90a36758e Fix heading 2020-07-22 07:00:48 -04:00
Cory LaViska
e294ff1c7d Update changelog 2020-07-21 15:33:58 -04:00
Cory LaViska
a91f1d15d6 Merge branch 'next' of https://github.com/shoelace-style/shoelace into next 2020-07-21 15:23:19 -04:00
Andrew Desmarais
38ce5e4a31 Small typo in example (#130) 2020-07-21 15:21:54 -04:00
Michael Stramel
2821cacb37 Switch lock array to set operations (#131)
* Switch lock array to set operations

* Remove falsy/null check from lockBodyScrolling function
2020-07-21 15:21:35 -04:00
Cory LaViska
ce30c35663 Move bindings from constructor to connectedCallback 2020-07-21 15:18:58 -04:00
Cory LaViska
206ecccce5 Update verbiage 2020-07-21 15:09:05 -04:00
Cory LaViska
27cf48849c Update custom elements example 2020-07-21 09:21:52 -04:00
Cory LaViska
5237b2be6b Update custom elements docs 2020-07-21 09:19:12 -04:00
Cory LaViska
57b8632eb7 Make tag colors AA compliant; fixes #128 2020-07-21 06:38:21 -04:00
Cory LaViska
0235320dab Add host + base element info 2020-07-20 17:13:54 -04:00
Cory LaViska
7a4fec532c Refactor host vars and remove non-display props 2020-07-20 16:58:29 -04:00
Cory LaViska
b45ca1a6d3 Expose --focus-ring prop on tab 2020-07-20 16:56:35 -04:00
Cory LaViska
45a38ea66f 2.0.0-beta.7 2020-07-20 16:36:12 -04:00
Cory LaViska
e8abc0bd75 Update changelog 2020-07-20 16:31:30 -04:00
Cory LaViska
1595a4d0db Fix touch icon size 2020-07-20 16:22:45 -04:00
Cory LaViska
bfe67e5b88 Improve rating selection 2020-07-20 16:22:32 -04:00
Cory LaViska
27f2f0d769 Fix clearable tags demo 2020-07-20 16:20:58 -04:00
Cory LaViska
61f06ca148 Improve custom elements installation instructions 2020-07-20 12:58:56 -04:00
Cory LaViska
aaa9187b84 Add rating component 2020-07-20 12:58:05 -04:00
Cory LaViska
12e6102d87 Merge branch 'next' into rating 2020-07-20 07:00:57 -04:00
Cory LaViska
c11c006f01 Update changelog 2020-07-20 07:00:38 -04:00
Cory LaViska
5d4421ec50 Add v1 links 2020-07-20 06:59:54 -04:00
Cory LaViska
b57151f282 Initial commit for rating (unfinished) 2020-07-20 06:17:20 -04:00
Cory LaViska
fb99adc25e 2.0.0-beta.6 2020-07-19 11:35:42 -04:00
Cory LaViska
95016b3178 Update changelog 2020-07-19 11:34:37 -04:00
Cory LaViska
567ebf3914 Fix typo 2020-07-19 11:34:12 -04:00
Cory LaViska
8911ea222d Add custom elements bundle docs 2020-07-19 11:30:01 -04:00
Cory LaViska
2a94db7b09 Fix nav spacing 2020-07-19 11:26:40 -04:00
Cory LaViska
7f7b68bbee Enable the custom elements bundle; fixes #108 2020-07-19 11:14:23 -04:00
Cory LaViska
4c2a8fdb7c Merge branch 'lamplightdev-fix/form-controls' into next 2020-07-18 20:39:23 -04:00
Chris Haynes
5709d993ef Fixes #109 - ensure sl-form finds all nested controls 2020-07-18 22:56:18 +01:00
Cory LaViska
aaf0f9f69e Update theming docs 2020-07-18 07:38:45 -04:00
356 changed files with 45400 additions and 17568 deletions

View File

@@ -1,39 +0,0 @@
{
"parserOptions": {
"project": "./tsconfig.json"
},
"extends": ["plugin:@stencil/recommended"],
"rules": {
"@stencil/async-methods": "error",
"@stencil/ban-prefix": ["error", ["stencil", "stnl", "st"]],
"@stencil/decorators-context": "error",
"@stencil/decorators-style": [
"error",
{
"prop": "inline",
"state": "inline",
"element": "inline",
"event": "inline",
"method": "multiline",
"watch": "multiline",
"listen": "multiline"
}
],
"@stencil/element-type": "error",
"@stencil/host-data-deprecated": "error",
"@stencil/methods-must-be-public": "error",
"@stencil/no-unused-watch": "error",
"@stencil/own-methods-must-be-private": "off",
"@stencil/own-props-must-be-private": "off",
"@stencil/prefer-vdom-listener": "error",
"@stencil/props-must-be-public": "off",
"@stencil/props-must-be-readonly": "off",
"@stencil/render-returns-host": "error",
"@stencil/required-jsdoc": "error",
"@stencil/reserved-member-names": "error",
"@stencil/single-export": "error",
"@stencil/strict-boolean-conditions": "off",
"@stencil/strict-mutable": "off",
"react/jsx-no-bind": "off"
}
}

View File

@@ -1,38 +1,36 @@
---
name: Bug Report
about: Create a report to help us improve.
about: Create a bug report to help us fix a demonstrable problem with code in the library.
title: ''
labels: bug
assignees: claviska
---
**Describe the bug**
A clear and concise description of what the bug is.
### Describe the bug
A bug is _a demonstrable problem_ caused by code in the library. Please provide a clear and concise description of what the bug is here.
**To Reproduce**
### To Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
2. Click on '...'
3. Scroll down to '...'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
### Demo
**Screenshots**
If applicable, add screenshots to help explain your problem.
If the bug isn't obvious, please provide a link to a CodePen or Fiddle with a minimal reproduction. Bugs that have repros get attention faster than those that don't.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
Tip: use the CodePen button on any example in the docs!
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
### Screenshots
If applicable, add screenshots to help explain the bug.
**Additional context**
Add any other context about the problem here.
### Browser / OS
- OS: [e.g. Mac, Windows]
- Browser [e.g. Chrome, Firefox, Safari]
- Browser version [e.g. 22]
### Additional information
Provide any additional information about the bug here.

View File

@@ -1,4 +1,4 @@
contact_links:
- name: Personal Support
url: https://github.com/sponsors/claviska
about: Support for issues outside the scope of the library can be obtained via sponsorship.
- name: Help & Support
url: https://github.com/shoelace-style/shoelace/discussions/categories/help
about: Please don't create issues for personal help requests. Instead, ask your question on the discussion forum.

View File

@@ -7,14 +7,11 @@ assignees: claviska
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
### What issue are you having?
Provide a clear and concise description of the problem you're facing.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
### Describe the solution you'd like
How would you like to see the library solve it?
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
### Describe alternatives you've considered
In what ways have you tried to solve this with the current version?

31
.github/workflows/node.js.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ next ]
pull_request:
branches: [ next ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test

17
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
# This workflow will create a GitHub release every time a tag is pushed
name: Create GitHub Release
on:
push:
tags:
- "v2.*"
- "v3.*"
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: "marvinpinto/action-automatic-releases@v1.2.1"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: false

39
.gitignore vendored
View File

@@ -1,34 +1,7 @@
src/components/*/readme.md
src/components/icon/icons
docs/assets/data/custom.json
docs/assets/icons/sprite.svg
dist/
docs/dist/
loader/
temp/
www/
*~
*.sw[mnpcod]
*.log
*.lock
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
.cache/
.stencil/
.idea/
.vscode/
.sass-cache/
.versions/
node_modules/
$RECYCLE.BIN/
.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate
.env
.cache
docs/dist
docs/search.json
dist
examples
node_modules

View File

@@ -1,12 +1,10 @@
.github
*.hbs
*.md
.cache
.stencil
.github
dist
docs/assets
docs/**/*.md
loader
docs/*.md
src/components/icon/icons
node_modules
src/components/**/readme.md
src/components.d.ts
www
package-lock.json
tsconfig.json

8
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"recommendations": [
"ms-vscode.vscode-typescript-tslint-plugin",
"esbenp.prettier-vscode",
"bierner.lit-html",
"bashmish.es6-string-css"
]
}

4
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}

View File

@@ -1,32 +0,0 @@
# Changelog
## 2.0.0-beta.5
- Fixed bug where `npm install` would fail due to postinstall script
- Removed unused dependency
## 2.0.0-beta.4
- Added `pill` variation to badges
- Fixed a bug where all badges had `pointer-events: none`
- Fixed `@since` props to show 2.0 instead of 1.0
- Fixed giant cursors in inputs in Safari
- Fixed color picker input width in Safari
- Fixed initial transitions for drawer, dialog, and popover consumers
- Fixed a bug where dialog, dropdown, and drawer would sometimes not transition in on the first open
- Fixed various documentation typos
## 2.0.0-beta.3
- Fix version in docs
- Remove custom elements bundle
## 2.0.0-beta.2
- Fix quick start and installation URLs
- Switch Docsify theme
- Update line heights tokens
## 2.0.0-beta.1
- Initial release

View File

@@ -1,117 +1,5 @@
# Contributing to Shoelace
Shoelace is an open source project, meaning everyone can use it and contribute to its development. Please take a moment to review these guidelines to make the contribution process as easy as possible for both you and the project's maintainers.
Before contributing, please review the contributions guidelines at:
## Using the Issue Tracker
The [issue tracker](https://github.com/shoelace-style/shoelace/issues) is for bug reports, feature requests, and pull requests.
- Please **do not** use the issue tracker for personal support requests. Please [ask your question](https://stackoverflow.com/questions/ask) on StackOverflow instead.
- Please **do not** derail, hijack, or troll issues. Keep the discussion on topic and be respectful of others.
- Please **do not** post comments with "+1" or "👍". Use [reactions](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) instead.
- Please **do** use the issue tracker for feature requests, bug reports, and pull requests.
Issues that do not follow these guidelines are subject to closure. There simply aren't enough resources for the author and contributors to troubleshoot personal support requests.
### Feature Requests
Feature requests can be added using the issue tracker.
- Please **do** search for an existing request before suggesting a new feature.
- Please **do** use the "👍" reaction to vote for a feature.
- Please **do** share substantial use cases and perspective that support new features if they haven't already been mentioned.
- Please **do not** bump, spam, or ping contributors to prioritize your own feature.
If you would like your feature prioritized, please consider [sponsoring the project](https://github.com/sponsors/claviska).
### Bug Reports
A bug is _a demonstrable problem_ caused by code in the library. Bug reports are an important contribution to the quality of the project. When submitting a bug report, there are a few steps you can take to make sure your issues gets attention quickly.
- Please **do not** paste in large blocks of irrelevant code
- Please **do** search for an existing issue before creating a new one
- Please **do** explain the bug clearly
- Please **do** provide a minimal test case that demonstrates the bug (e.g. [jsfiddle.net](https://jsfiddle.net/) or [CodePen](https://codepen.io/))
- Please **do** provide additional information, when necessary, to replicate the bug
**A minimal test case is critical to a successful bug report.** It demonstrates that the bug exists in the library and not in surrounding code. Contributors should be able to understand the bug without studying your code, otherwise they'll probably move on to another bug.
If you would like your bug prioritized, please consider [sponsoring the project](https://github.com/sponsors/claviska).
### Pull Requests
To keep the project on track, please consider the following guidelines before submitting a PR.
- Please **do not** submit a PR without opening an issue first, especially for non-trivial changes. This may prevent you from doing work that won't be accepted for various reasons (e.g. someone is already working on it, it's not a good fit for the project, it needs additional planning, etc.)
- Please **do** make sure your PR clearly defines what you're changing. Even if you feel your changes are obvious, please explain them so other contributors can more easily review your works. PRs without detailed descriptions are subject to closure pending more details.
- Please **do not** edit anything in `dist/`. These files are generated automatically, so you need to edit the source files instead.
The author reserves the right to reject any PR that's outside the scope of the project or doesn't meet code quality standards.
### Branches
`master` - This branch reflects the latest release and powers [shoelace.style](https://shoelace.style/).
`next` - This branch is where pull requests will land. It reflects what's coming in the _next_ release, which can be previewed at [next.shoelace.style](https://next.shoelace.style/).
## Conventions
This section aims to describe some of the design decisions and code conventions that support the project. All contributors are expected to follow conventions and best practices, even those not explicitly defined in this document. When in doubt, refer to existing source code and execute your best judgment.
In order to keep the project in a maintainable state, code that doesn't follow conventions and best practices will need to be refactored before it will be accepted. This isn't a knock on your code or your style — it's something the author considers necessary to operate a successful open source project.
### Semantic Versioning
This project follows [Semantic Versioning](https://semver.org/). Breaking changes in stable components will not be accepted until the next major version. As such, all contributions must consider the project's roadmap and take this into consideration. Features that are deemed no longer necessary in future versions will be deprecated instead.
**Components marked "experimental" should not be used in production,** as changes to them will not be subject to this rule.
### Code Formatting & Linting
The majority of code formatting is handled automatically by [Prettier](https://prettier.io/) at build time. However, for the best experience, you should [install it in your editor](https://prettier.io/docs/en/editors.html) and enable format on save.
Linting is run automatically at build time. By design, the project will not build if the linter is unhappy. Contributors are strongly encouraged to install an ESLint plugin for your editor for the best developer experience.
### BEM Class Names
All components use a [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM), so styles are completely encapsulated from the rest of the document. As a result, class names _inside_ a component won't conflict with class names _outside_ the component, so we're free to name them whatever we want.
Internally, each component uses the [BEM methodology](http://getbem.com/) for its class names. There is no technical requirement to do this — it's purely the preference of the author. However, all contributions are expected to follow this practice for the sake of consistency.
## Developer Tips
### Documentation is the key to success
Nobody likes writing documentation, but not having good docs is frustrating to users and makes the project less appealing. Fortunately, writing documentation for Shoelace is really easy!
A lot of the documentation is generated automatically based on JSDoc comments in each component's source code. If you have ESLint enabled, your editor will tell you when a comment is missing. This may feel a bit naggy, but it's a very good thing. Every property, method, event, etc. is documented this way. By adding comments as you code, the docs are more easily kept up to date.
The documentation pages are served up by [Docsify](https://docsify.now.sh/). Check out `docs/_sidebar.md` and `docs/components/` to get an idea of how pages are created and formatted. If you're creating a new component, it may help to use an existing component's markdown file as a template.
If you need help with documentation, feel free to reach out!
### Choose composability when possible
When designed right, web components are highly composable, meaning you can easily reuse them in other components. This reduces the overall size of the library, expedites feature development, and maintains a consistent user experience throughout.
The select component, for example, makes use of the dropdown, input, and menu components. Because it's offloading most of its functionality and styles to these lower-level components, the select component remains very lightweight and its appearance and behavior is consistent with other form controls and menus.
### When to use a standard property vs. a CSS custom property
When designing a component's API, standard properties ("props") are generally used to change the _behavior_ of a component, whereas CSS custom properties ("CSS variables") are used to change the _appearance_ of a component. Remember that props can't respond to media queries, but CSS variables can.
There are some exceptions to this (e.g. when it significantly improves developer experience), but a good rule of thumbs is "will this need to change based on screen size?" If so, you probably want to use a CSS variable.
### Boolean Props
Boolean props should _always_ default to `false`, otherwise there's no way for the user to unset it without JavaScript. To keep the API as friendly and consistent as possible, use a name like `noHeader` with a default value of `false` instead of `header` with a default value of `true`.
### A Note About Sass
The Shoelace _source_ is developed using Sass for the convenience of nested selectors, imports, and tedious things such as color palette generation. By design, Sass variables, color functions, and other preprocessor-specific feaures are not used in the source and will not be accepted in a PR.
Consumers of the library should never need to worry about preprocessing the library.
### Positioning Popovers
Shoelace uses an internal popover utility for dropdowns, tooltips, etc. This is a light abstraction of Popper.js designed to make positioning and transitioning things easy and consistent throughout the library. When possible, use this utility instead of relying on Popper directly. See `src/utilities/popover.ts` for details.
[shoelace.style/resources/contributing](https://shoelace.style/resources/contributing)

View File

@@ -5,6 +5,8 @@ A forward-thinking library of web components.
- Works with all frameworks 🧩
- Works with CDNs 🚛
- Fully customizable with CSS 🎨
- Includes an official dark theme 🌛
- Built with accessibility in mind ♿️
- Open source 😸
Designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska).
@@ -21,7 +23,7 @@ Twitter: [@shoelace_style](https://twitter.com/shoelace_style)
## Shoemakers 🥾
Shoemakers, or "developers," can use this documentation to learn how to build Shoelace from source.
Shoemakers, or "Shoelace developers," can use this documentation to learn how to build Shoelace from source. You will need Node >= 14 to build and run the project locally. It is preferred, but not required, to use npm 7.
**You don't need to do any of this to use Shoelace!** This page is for people who want to contribute to the project, tinker with the source, or create a custom build of Shoelace.
@@ -29,15 +31,13 @@ If that's not what you're trying to do, the [documentation website](https://shoe
### What are you using to build Shoelace?
Components are built with [Stencil](https://stenciljs.com/), a compiler that generates standards-based web components. The source code is a combination of TypeScript + JSX (TSX). Stylesheets are written in SCSS.
The build is done through a combination of Stencil's CLI and a handful of custom scripts.
Components are built with [LitElement](https://lit-element.polymer-project.org/), a custom elements base class that provides an intuitive API and reactive data binding. The build is a custom script with bundling powered by [esbuild](https://esbuild.github.io/).
### Forking the Repo
Start by [forking the repo](https://github.com/shoelace-style/shoelace/fork) on GitHub, then clone it locally and install dependencies.
```sh
```bash
git clone https://github.com/YOUR_GITHUB_USERNAME/shoelace
cd shoelace
npm install
@@ -47,24 +47,32 @@ npm install
Once you've cloned the repo, run the following command.
```sh
npm run start
```bash
npm start
```
This will spin up the Shoelace dev server. Note that the dev server requires ports 4000, 4001, and 4002 to be available.
This will spin up the Shoelace dev server. After the initial build, a browser will open automatically. There is currently no hot module reloading (HMR), as browser's don't provide a way to reregister custom elements, but most changes to the source will reload the browser automatically.
After the initial build, a browser will open at `http://localhost:4000`.
Hot module reloading (HMR) is enabled for components, so changes will instantly reflect in the browser as you work. The documentation is powered by Docsify, which uses raw markdown files to generate pages. As such, no static files are built for the docs. Unfortunately, changes to _documentation pages_ will trigger a page refresh (no HMR).
The documentation is powered by Docsify, which uses raw markdown files to generate pages. As such, no static files are built for the docs.
### Building
To generate a production build, run the following command.
```sh
```bash
npm run build
```
### Creating New Components
To scaffold a new component, run the following command, replacing `sl-tag-name` with the desired tag name.
```bash
npm run create sl-tag-name
```
This will generate a source file, a stylesheet, and a docs page for you. When you start the dev server, you'll find the new component in the "Components" section of the sidebar.
### Contributing
Shoelace is an open source project and contributions are encouraged! If you're interesting in contributing, please review the [contribution guidelines](CONTRIBUTING.md) first.

View File

@@ -0,0 +1,86 @@
import fs from 'fs';
import commentParser from 'comment-parser';
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const { name, description, version, author, homepage, license } = packageData;
const noDash = string => string.replace(/^\s?-/, '').trim();
export default {
globs: ['src/components/**/*.ts'],
exclude: ['**/*.test.ts'],
plugins: [
// Append package data
{
name: 'shoelace-package-data',
packageLinkPhase({ customElementsManifest, context }) {
customElementsManifest.package = { name, description, version, author, homepage, license };
}
},
// Parse custom jsDoc tags
{
name: 'shoelace-custom-tags',
analyzePhase({ ts, node, moduleDoc, context }) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration:
const className = node.name.getText();
const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
const customTags = ['animation', 'dependency', 'since', 'status'];
let customComments = '/**';
node.jsDoc?.forEach(jsDoc => {
jsDoc?.tags?.forEach(tag => {
const tagName = tag.tagName.getText();
if (customTags.includes(tagName)) {
customComments += `\n * @${tagName} ${tag.comment}`;
}
});
});
const parsed = commentParser.parse(customComments + '\n */');
parsed[0].tags?.map(t => {
switch (t.tag) {
// Animations
case 'animation':
if (!Array.isArray(classDoc['animations'])) {
classDoc['animations'] = [];
}
classDoc['animations'].push({
name: t.name,
description: noDash(t.description)
});
break;
// Dependencies
case 'dependency':
if (!Array.isArray(classDoc['dependencies'])) {
classDoc['dependencies'] = [];
}
classDoc['dependencies'].push(t.name);
break;
// Value-only metadata tags
case 'since':
case 'status':
classDoc[t.tag] = t.name;
break;
// All other tags
default:
if (!Array.isArray(classDoc[t.tag])) {
classDoc[t.tag] = [];
}
classDoc[t.tag].push({
name: t.name,
description: t.description,
type: t.type || undefined
});
}
});
}
}
}
]
};

View File

@@ -1,76 +0,0 @@
//
// The Shoelace dev server! 🥾
//
// This is an Express + Browsersync script that:
//
// - Proxies Stencil's dev server (for HMR of components)
// - Serves dist/ and docs/ from https://localhost:3000/
// - Launches the docs site and reloads the page when pages are modified
//
// Usage:
//
// 1. Run Stencil: `stencil build --dev --docs --watch --serve --no-open`
//
// 2. Run this script at the same time as Stencil
//
const bs = require('browser-sync').create();
const chalk = require('chalk');
const express = require('express');
const fs = require('fs').promises;
const path = require('path');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const browserPort = 4000;
const stencilPort = 4001;
const proxyPort = 4002;
// Proxy Stencil's dev server
app.use(
'/~dev-server',
createProxyMiddleware({
target: `http://localhost:${stencilPort}`,
changeOrigin: true,
ws: true
})
);
// Inject Stencil's dev server iframe into the main entry point
app.use(/^\/$/, async (req, res, next) => {
let index = await fs.readFile('./docs/index.html', 'utf8');
index = index
.replace('<head>', '<head><script>window.ShoelaceDevServer = true;</script>')
.replace(
'</body>',
'<iframe src="/~dev-server" style="display: block; width: 0; height: 0; border: 0;"></iframe></body>'
);
res.type('html').send(index);
});
app.use('/dist', express.static('./dist'));
app.use('/', express.static('./docs'));
app.listen(proxyPort);
// Give Stencil's dev server a few seconds to spin up, then launch the browser
setTimeout(() => {
console.log(chalk.cyan(`\nLaunching the Shoelace dev server at http://localhost:${browserPort}! 🥾\n`));
bs.init({
startPath: '/',
port: browserPort,
proxy: {
target: `http://localhost:${proxyPort}`,
ws: true
},
logLevel: 'silent',
notify: false,
snippetOptions: {
ignorePaths: '/~dev-server'
}
});
// Reload when docs change
bs.watch('docs/**/*').on('change', async () => {
bs.reload();
});
}, 5000);

View File

View File

@@ -1,3 +1,5 @@
# Not Found
Sorry, I couldn't find that page.
<img class="not-found-image" src="/assets/images/undraw-not-found.svg" alt="Cute monsters hiding behind a tree">
Sorry, I couldn't find that page. Have you tried pressing <kbd>/</kbd> to search?

View File

@@ -1,49 +1,81 @@
- Getting Started
- [Overview](/)
- [Installation](/getting-started/installation.md)
- [Usage](/getting-started/usage.md)
- [Customizing](/getting-started/customizing.md)
- [Roadmap](/getting-started/roadmap.md)
- [Installation](/getting-started/installation)
- [Usage](/getting-started/usage)
- [Themes](/getting-started/themes)
- [Customizing](/getting-started/customizing)
- Resources
- [Community](/resources/community)
- [Contributing](/resources/contributing)
- [Changelog](/resources/changelog)
- Components
- [Alert](/components/alert)
- [Avatar](/components/avatar)
- [Badge](/components/badge)
- [Breadcrumb](/components/breadcrumb)
- [Breadcrumb Item](/components/breadcrumb-item)
- [Button](/components/button)
- [Button Group](/components/button-group)
- [Card](/components/card)
- [Checkbox](/components/checkbox)
- [Color Picker](/components/color-picker)
- [Context Menu](/components/context-menu)
- [Details](/components/details)
- [Dialog](/components/dialog)
- [Divider](/components/divider)
- [Drawer](/components/drawer)
- [Dropdown](/components/dropdown)
- [Form](/components/form)
- [Icon](/components/icon)
- [Icon Button](/components/icon-button)
- [Image Comparer](/components/image-comparer)
- [Input](/components/input)
- [Menu](/components/menu)
- [Menu Item](/components/menu-item)
- [Menu Label](/components/menu-label)
- [Progress Bar](/components/progress-bar)
- [Progress Ring](/components/progress-ring)
- [QR Code](/components/qr-code)
- [Radio](/components/radio)
- [Radio Group](/components/radio-group)
- [Range](/components/range)
- [Rating](/components/rating)
- [Select](/components/select)
- [Skeleton](/components/skeleton)
- [Spinner](/components/spinner)
- [Switch](/components/switch)
- [Tab Group](/components/tab-group)
- [Tab](/components/tab)
- [Tab Panel](/components/tab-panel)
- [Tag](/components/tag)
- [Textarea](/components/textarea)
- [Tooltip](/components/tooltip)
<!--plop:component-->
- [Alert](/components/alert.md)
- [Avatar](/components/avatar.md)
- [Badge](/components/badge.md)
- [Button](/components/button.md)
- [Checkbox](/components/checkbox.md)
- [Color Picker](/components/color-picker.md)
- [Details](/components/details.md)
- [Dialog](/components/dialog.md)
- [Drawer](/components/drawer.md)
- [Dropdown](/components/dropdown.md)
- [Form](/components/form.md)
- [Icon](/components/icon.md)
- [Input](/components/input.md)
- [Menu](/components/menu.md)
- [Menu Divider](/components/menu-divider.md)
- [Menu Item](/components/menu-item.md)
- [Menu Label](/components/menu-label.md)
- [Progress Bar](/components/progress-bar.md)
- [Progress Ring](/components/progress-ring.md)
- [Radio](/components/radio.md)
- [Range](/components/range.md)
- [Select](/components/select.md)
- [Spinner](/components/spinner.md)
- [Switch](/components/switch.md)
- [Tab Group](/components/tab-group.md)
- [Tab](/components/tab.md)
- [Tab Panel](/components/tab-panel.md)
- [Tag](/components/tag.md)
- [Textarea](/components/textarea.md)
- [Tooltip](/components/tooltip.md)
- Utilities
- [Animated Image](/components/animated-image)
- [Animation](/components/animation)
- [Format Bytes](/components/format-bytes)
- [Format Date](/components/format-date)
- [Format Number](/components/format-number)
- [Include](/components/include)
- [Mutation Observer](/components/mutation-observer)
- [Relative Time](/components/relative-time)
- [Resize Observer](/components/resize-observer)
- [Responsive Media](/components/responsive-media)
- Design Tokens
- [Typography](/tokens/typography.md)
- [Color](/tokens/color.md)
- [Spacing](/tokens/spacing.md)
- [Elevation](/tokens/elevation.md)
- [Border Radius](/tokens/border-radius.md)
- [Transition](/tokens/transition.md)
- [Z-index](/tokens/z-index.md)
- [Typography](/tokens/typography)
- [Color](/tokens/color)
- [Spacing](/tokens/spacing)
- [Elevation](/tokens/elevation)
- [Border Radius](/tokens/border-radius)
- [Transition](/tokens/transition)
- [Z-index](/tokens/z-index)
- Tutorials
- [Integrating with Laravel](/tutorials/integrating-with-laravel)
- [Integrating with NextJS](/tutorials/integrating-with-nextjs)
- [Integrating with Rails](/tutorials/integrating-with-rails)

View File

@@ -0,0 +1,19 @@
<p style="margin-top: 0">
The content in this example was included from
<a href="/assets/examples/include.html" target="_blank">a separate file</a>. 🤯
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi. Fringilla urna porttitor rhoncus dolor purus
non enim. Nullam vehicula ipsum a arcu cursus vitae congue mauris. Gravida in fermentum et sollicitudin.
</p>
<p>
Cursus sit amet dictum sit amet justo donec enim. Sed id semper risus in hendrerit gravida. Viverra accumsan in nisl
nisi scelerisque eu ultrices vitae. Et molestie ac feugiat sed lectus vestibulum mattis ullamcorper velit. Nec
ullamcorper sit amet risus nullam. Et egestas quis ipsum suspendisse ultrices gravida dictum. Lorem donec massa sapien
faucibus et molestie. A cras semper auctor neque vitae.
</p>
<script>
console.log('This will only execute if the `allow-scripts` prop is present');
</script>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 688 KiB

View File

@@ -1 +0,0 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub icon</title><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>

Before

Width:  |  Height:  |  Size: 848 B

View File

@@ -1,6 +1,6 @@
<svg viewBox="0 0 127 141" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill-rule="nonzero" fill="#409eff">
<g fill-rule="nonzero" fill="#0ea5e9">
<path d="M102.375,90.85 C102.979,90.557 103.57,90.215 104.15,89.826 L106.425,88.501 C106.848,88.19 107.64,87.573 108.8,86.65 L108.95,86.501 C109.883,85.567 110.916,85.117 112.05,85.15 C112.55,85.15 113.133,85.284 113.8,85.55 L122.3,78 C122.533,77.8 122.767,77.633 123,77.5 L123.05,77.5 C123.95,76.967 124.7,77 125.3,77.6 C126.367,78.166 126.45,79.133 125.55,80.5 L116.65,88.399 C116.717,88.533 116.75,88.666 116.75,88.799 C116.883,89.399 116.833,89.999 116.6,90.599 C116.4,90.999 116.117,91.382 115.75,91.749 C115.379,92.145 114.996,92.528 114.6,92.898 L109.45,96.648 C108.99,96.97 108.523,97.27 108.05,97.548 C107.46,97.906 106.86,98.232 106.25,98.523 C105.985,98.644 105.718,98.76 105.45,98.874 C103.841,99.559 102.174,100.017 100.45,100.249 C99.65,106.982 97.35,113.183 93.55,118.849 C88.75,125.915 82.183,131.299 73.85,134.999 C65.55,138.699 56.567,140.549 46.9,140.549 C33.567,140.415 22.75,137.415 14.45,131.549 C4.817,124.75 0,115.7 0,104.399 L0,102.849 C0.333,95.149 2.6,87.849 6.8,80.95 C10.933,74.116 16.983,69.5 24.95,67.1 C29.05,65.9 33.166,65.3 37.3,65.3 C41.567,65.3 45.967,66.083 50.5,67.65 C55.033,69.216 60.15,71.916 65.85,75.75 L80.7,85.7 C84.833,88.399 88.6,90.233 92,91.2 C91.3,84.3 88.8,78.399 84.5,73.5 C80.2,68.533 74.717,64.9 68.05,62.6 L61.65,60.4 C55.783,58.333 51.417,56.3 48.55,54.3 C40.817,49.067 36.517,41.883 35.65,32.75 L35.5,30.05 C35.5,21.25 39.067,13.883 46.2,7.95 C52.567,2.65 60.133,0 68.9,0 C75.5,0 81.417,1.9 86.65,5.7 C91.917,9.533 94.9,14.967 95.6,22 L95.75,24.75 C95.75,29.85 94.433,34.216 91.8,37.85 C89.1,41.483 86.717,43.3 84.65,43.3 C84.21,43.269 83.802,43.21 83.425,43.125 L74.1,51.9 C72.6,52.733 71.583,52.583 71.05,51.45 C70.517,50.85 70.567,50.1 71.2,49.2 L71.25,49.15 C71.383,48.95 71.567,48.733 71.8,48.5 L80.475,40.275 C80.376,39.872 80.318,39.431 80.3,38.95 C80.3,37.817 80.75,36.867 81.65,36.1 C85.45,32.7 87.35,28.784 87.35,24.35 C87.35,19.95 85.683,16.25 82.35,13.25 C79.017,10.25 74.467,8.716 68.7,8.65 C61.5,8.65 55.583,10.817 50.95,15.15 C46.317,19.483 44,24.683 44,30.75 C44,35.65 45.883,40.066 49.65,44 C53.383,47.9 59.15,50.966 66.95,53.2 C77.883,56.367 86.233,61.7 92,69.2 C97.133,75.833 100,83.283 100.6,91.55 C101.199,91.365 101.791,91.132 102.375,90.85 Z M71.95,49.05 C71.95,49.35 72.117,49.5 72.45,49.5 C72.483,49.5 75.117,47.066 80.35,42.2 C80.35,41.533 78.95,42.45 76.15,44.95 C73.35,47.483 71.95,48.85 71.95,49.05 Z M74.15,50.8 C74.15,50.533 74.017,50.4 73.75,50.4 C73.45,50.4 73.183,50.55 72.95,50.85 C72.416,50.817 72.033,50.884 71.8,51.05 C71.7,51.117 71.65,51.183 71.65,51.25 C71.65,51.45 71.783,51.6 72.05,51.7 L72.95,51.7 C73.75,51.4 74.15,51.1 74.15,50.8 Z M80.35,45.35 C80.35,44.583 79.9,44.583 79,45.35 C78.567,45.75 78.017,46.317 77.35,47.05 C77.117,47.217 76.633,47.667 75.9,48.4 C75.133,49.2 74.75,49.683 74.75,49.85 L74.8,50.2 C75,50.267 75.133,50.3 75.2,50.3 C75.233,50.3 76.1,49.5 77.8,47.9 C79.5,46.3 80.35,45.45 80.35,45.35 Z M124.2,78.3 L115.8,85.7 C116.3,85.967 116.667,86.349 116.9,86.849 L125.2,79.45 C125.266,79.116 125.217,78.849 125.05,78.649 C124.883,78.517 124.6,78.399 124.2,78.3 Z M123.75,78.05 L123.55,77.85 L116.15,83.85 L116.6,84.4 L123.75,78.05 Z M91.85,99.899 C89.65,99.333 87.617,98.649 85.75,97.849 C81.55,96.149 76.333,93.183 70.1,88.95 L59.85,82 C55.517,79.233 51.567,77.166 48,75.8 C44.4,74.467 40.867,73.8 37.4,73.8 L35.9,73.8 C27.067,74.267 20.2,77.583 15.3,83.75 C10.734,89.45 8.45,96.184 8.45,103.95 C8.45,112.683 11.95,119.516 18.95,124.45 C25.916,129.416 35.467,131.899 47.6,131.899 C57.133,131.899 65.166,130.2 71.7,126.799 C78.2,123.399 83.25,118.899 86.85,113.299 C89.55,109.033 91.217,104.566 91.85,99.899 Z"></path>
</g>
</g>

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 29 KiB

BIN
docs/assets/images/tie.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -1 +0,0 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter icon</title><path fill="currentColor" d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"/></svg>

Before

Width:  |  Height:  |  Size: 778 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
docs/assets/images/walk.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,22 +1,34 @@
.code-block {
position: relative;
border-radius: 3px;
background: hsl(var(--sl-color-gray-hue), var(--sl-color-gray-saturation), 97%);
background-color: rgb(var(--sl-color-neutral-50));
margin-bottom: 1.5rem;
}
.code-block__preview {
position: relative;
border: solid 1px var(--sl-color-gray-90);
border: solid 1px rgb(var(--sl-color-neutral-200));
border-bottom: none;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
background-color: white;
background-color: rgb(var(--sl-color-neutral-0));
min-width: 20rem;
max-width: 100%;
padding: 1.5rem 3.25rem 1.5rem 1.5rem;
}
/* Block the preview while dragging to prevent iframes from intercepting drag events */
.code-block__preview--dragging:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: ew-resize;
}
.code-block__resizer {
display: flex;
align-items: center;
@@ -27,9 +39,9 @@
bottom: 0;
width: 1.75rem;
font-size: 20px;
color: var(--sl-color-gray-50);
background-color: white;
border-left: solid 1px var(--sl-color-gray-90);
color: rgb(var(--sl-color-neutral-600));
background-color: rgb(var(--sl-color-neutral-0));
border-left: solid 1px rgb(var(--sl-color-neutral-200));
border-top-right-radius: 3px;
cursor: ew-resize;
transition: 250ms background-color;
@@ -46,63 +58,146 @@
}
.code-block__source {
border: solid 1px var(--sl-color-gray-90);
border: solid 1px rgb(var(--sl-color-neutral-200));
border-bottom: none;
border-radius: 0 !important;
margin: 0 !important;
margin: 0;
display: none;
}
.code-block__source .docsify-copy-code-button {
border-top-right-radius: 0;
}
.code-block--expanded .code-block__source {
display: block;
}
.code-block__buttons {
position: relative;
border: solid 1px rgb(var(--sl-color-neutral-200));
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
display: flex;
}
.code-block__button {
flex: 0 0 auto;
height: 2.5rem;
min-width: 2.5rem;
border: none;
border-radius: 0;
background: rgb(var(--sl-color-neutral-0));
font: inherit;
font-size: 0.7rem;
font-weight: 500;
text-transform: uppercase;
color: rgb(var(--sl-color-neutral-600));
padding: 0 1rem;
cursor: pointer;
}
.code-block__button:not(:last-of-type) {
border-right: solid 1px rgb(var(--sl-color-neutral-200));
}
.code-block__button--codepen {
display: flex;
place-items: center;
width: 6rem;
}
.code-block__button:first-of-type {
border-bottom-left-radius: 3px;
}
.code-block__button:last-of-type {
border-bottom-right-radius: 3px;
}
.code-block__button:hover,
.code-block__button:active {
box-shadow: 0 0 0 1px rgb(var(--sl-color-primary-400));
border-right-color: transparent;
background-color: rgb(var(--sl-color-primary-50));
color: rgb(var(--sl-color-primary-700));
z-index: 1;
}
.code-block__button:focus-visible {
outline: none;
color: rgb(var(--sl-color-primary-600));
border-color: rgb(var(--sl-color-primary-400));
border-right-color: transparent;
background-color: rgb(var(--sl-color-primary-50));
box-shadow: 0 0 0 1px rgb(var(--sl-color-primary-400)), var(--sl-focus-ring);
z-index: 2;
}
.code-block__toggle {
position: relative;
z-index: 1;
display: flex;
flex: 1 1 auto;
align-items: center;
justify-content: center;
width: 100%;
height: 2.5rem;
border: solid 1px var(--sl-color-gray-90);
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
background: var(--sl-color-white);
font: inherit;
font-size: 0.875rem;
color: var(--sl-color-gray-40);
color: rgb(var(--sl-color-neutral-600));
cursor: pointer;
transition: 250ms background-color;
-webkit-appearance: none;
}
.code-block__toggle:hover,
.code-block__toggle:active {
border-color: var(--sl-color-primary-80);
background-color: var(--sl-color-primary-95);
color: var(--sl-color-primary-50);
}
.code-block__toggle:focus {
outline: none;
border-color: var(--sl-color-primary-50);
background-color: var(--sl-color-primary-95);
color: var(--sl-color-primary-50);
box-shadow: var(--sl-focus-ring-box-shadow);
}
.code-block__toggle svg {
width: 1em;
height: 1em;
margin-left: 0.25rem;
transition: 250ms transform;
}
.code-block--expanded .code-block__toggle svg {
transform: rotate(180deg);
}
/* Copy button styles */
.markdown-section .docsify-copy-code-button {
top: 4px;
right: 4px;
background-color: rgb(var(--sl-color-neutral-600));
border-radius: var(--sl-border-radius-medium);
font-family: var(--sl-font-sans);
font-size: var(--sl-font-size-x-small);
font-weight: var(--sl-font-weight-semibold);
text-transform: uppercase;
padding: 8px;
user-select: none;
transition: 0.1s all;
}
.markdown-section .docsify-copy-code-button.copied {
animation: pulse 0.75s;
--pulse-color: rgb(var(--sl-color-neutral-600));
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 var(--pulse-color);
}
70% {
box-shadow: 0 0 0 0.5rem transparent;
}
100% {
box-shadow: 0 0 0 0 transparent;
}
}
.markdown-section .docsify-copy-code-button .label {
transition: none;
}
.markdown-section .docsify-copy-code-button .success,
.markdown-section .docsify-copy-code-button .error {
display: none;
}
.markdown-section .docsify-copy-code-button:focus-visible {
box-shadow: 0 0 0 3px rgb(var(--sl-color-neutral-500) / 50%);
}
.markdown-section .docsify-copy-code-button:active {
background-color: rgb(var(--sl-color-neutral-600));
transform: scale(0.92);
}

View File

@@ -7,13 +7,14 @@
function runScript(script) {
const newScript = document.createElement('script');
newScript.appendChild(
document.createTextNode(`
(() => {
${script.innerHTML}
})();
`)
);
if (script.type === 'module') {
newScript.type = 'module';
newScript.textContent = script.innerHTML;
} else {
newScript.appendChild(document.createTextNode(`(() => { ${script.innerHTML} })();`));
}
script.parentNode.replaceChild(newScript, script);
}
@@ -27,55 +28,66 @@
hook.afterEach(function (html, next) {
const domParser = new DOMParser();
const doc = domParser.parseFromString(html, 'text/html');
const codePenButton = `
<button type="button" class="code-block__button code-block__button--codepen" title="Edit on CodePen">
<svg
width="138"
height="26"
viewBox="0 0 138 26"
fill="none"
stroke="currentColor"
stroke-width="2.3"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M80 6h-9v14h9 M114 6h-9 v14h9 M111 13h-6 M77 13h-6 M122 20V6l11 14V6 M22 16.7L33 24l11-7.3V9.3L33 2L22 9.3V16.7z M44 16.7L33 9.3l-11 7.4 M22 9.3l11 7.3 l11-7.3 M33 2v7.3 M33 16.7V24 M88 14h6c2.2 0 4-1.8 4-4s-1.8-4-4-4h-6v14 M15 8c-1.3-1.3-3-2-5-2c-4 0-7 3-7 7s3 7 7 7 c2 0 3.7-0.8 5-2 M64 13c0 4-3 7-7 7h-5V6h5C61 6 64 9 64 13z" />
</svg>
</button>
`;
[...doc.querySelectorAll('code[class^="lang-"]')].map(code => {
if (code.classList.contains('preview')) {
const codeBlock = document.createElement('div');
const preview = document.createElement('div');
const pre = code.closest('pre');
const preId = `code-block-preview-${count}`;
const toggle = document.createElement('button');
const toggleId = `code-block-toggle-${count}`;
wrap(pre, codeBlock);
codeBlock.classList.add('code-block');
preview.classList.add('code-block__preview');
preview.innerHTML = code.textContent;
preview.innerHTML += `
<div class="code-block__resizer">
<sl-icon name="grip-horizontal"></sl-icon>
</div>
`;
pre.id = preId;
pre.classList.add('code-block__source');
pre.setAttribute('data-lang', pre.getAttribute('data-lang').replace(/ preview$/, ''));
pre.setAttribute('aria-labeledby', toggleId);
pre.setAttribute('aria-labelledby', toggleId);
toggle.id = toggleId;
toggle.type = 'button';
toggle.classList.add('code-block__toggle');
toggle.setAttribute('aria-expanded', 'false');
toggle.setAttribute('aria-controls', preId);
toggle.innerHTML = `
Source
const codeBlock = `
<div class="code-block">
<div class="code-block__preview">
${code.textContent}
<div class="code-block__resizer">
<sl-icon name="grip-vertical"></sl-icon>
</div>
</div>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
${pre.outerHTML}
<div class="code-block__buttons">
<button type="button" class="code-block__button code-block__toggle" aria-expanded="false" aria-controls="${preId}">
View Source
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
${!code.classList.contains('no-codepen') ? codePenButton : ''}
</div>
</div>
`;
codeBlock.prepend(preview);
codeBlock.append(toggle);
pre.replaceWith(domParser.parseFromString(codeBlock, 'text/html').body);
count++;
}
@@ -91,36 +103,87 @@
// Horizontal resizing
hook.doneEach(() => {
[...document.querySelectorAll('.code-block__preview')].map(resizeElement => {
[...document.querySelectorAll('.code-block__preview')].map(preview => {
const resizer = preview.querySelector('.code-block__resizer');
let startX;
let startY;
let startWidth;
let startHeight;
const initDrag = event => {
startX = event.clientX;
startY = event.clientY;
startWidth = parseInt(document.defaultView.getComputedStyle(resizeElement).width, 10);
startHeight = parseInt(document.defaultView.getComputedStyle(resizeElement).height, 10);
document.documentElement.addEventListener('mousemove', doDrag, false);
document.documentElement.addEventListener('mouseup', stopDrag, false);
const dragStart = event => {
startX = event.changedTouches ? event.changedTouches[0].pageX : event.clientX;
startWidth = parseInt(document.defaultView.getComputedStyle(preview).width, 10);
preview.classList.add('code-block__preview--dragging');
event.preventDefault();
document.documentElement.addEventListener('mousemove', dragMove, false);
document.documentElement.addEventListener('touchmove', dragMove, false);
document.documentElement.addEventListener('mouseup', dragStop, false);
document.documentElement.addEventListener('touchend', dragStop, false);
};
const doDrag = event => {
resizeElement.style.width = startWidth + event.clientX - startX + 'px';
const dragMove = event => {
setWidth(startWidth + (event.changedTouches ? event.changedTouches[0].pageX : event.pageX) - startX);
};
const stopDrag = event => {
document.documentElement.removeEventListener('mousemove', doDrag, false);
document.documentElement.removeEventListener('mouseup', stopDrag, false);
const dragStop = event => {
preview.classList.remove('code-block__preview--dragging');
document.documentElement.removeEventListener('mousemove', dragMove, false);
document.documentElement.removeEventListener('touchmove', dragMove, false);
document.documentElement.removeEventListener('mouseup', dragStop, false);
document.documentElement.removeEventListener('touchend', dragStop, false);
};
resizeElement.querySelector('.code-block__resizer').addEventListener('mousedown', initDrag);
const setWidth = width => (preview.style.width = width + 'px');
resizer.addEventListener('mousedown', dragStart);
resizer.addEventListener('touchstart', dragStart);
}, false);
});
});
// Open in CodePen
document.addEventListener('click', event => {
const button = event.target.closest('button');
if (button?.classList.contains('code-block__button--codepen')) {
const codeBlock = button.closest('.code-block');
const html = codeBlock.querySelector('.code-block__source > code').textContent;
const version = sessionStorage.getItem('sl-version');
const form = document.createElement('form');
form.action = 'https://codepen.io/pen/define';
form.method = 'POST';
form.target = '_blank';
// Docs: https://blog.codepen.io/documentation/prefill/
const data = {
title: '',
description: '',
tags: ['shoelace', 'web components'],
editors: '100',
head: `<meta name="viewport" content="width=device-width">`,
css_external: ``,
js_external: ``,
js_module: true,
html:
`<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${version}/dist/themes/light.css">\n` +
`<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${version}/dist/shoelace.js"></script>\n` +
`\n` +
html,
css: `body {\n font: 16px sans-serif;\n}`,
js: ``
};
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'data';
input.value = JSON.stringify(data);
form.append(input);
document.body.append(form);
form.submit();
form.remove();
}
});
// Expand and collapse code blocks
document.addEventListener('click', event => {
const toggle = event.target.closest('.code-block__toggle');
@@ -130,4 +193,16 @@
event.target.setAttribute('aria-expanded', codeBlock.classList.contains('code-block--expanded'));
}
});
// Show pulse when copying
document.addEventListener('click', event => {
const button = event.target.closest('.docsify-copy-code-button');
if (button) {
button.classList.remove('copied');
requestAnimationFrame(() => {
button.addEventListener('animationend', () => button.classList.remove('copied'), { once: true });
button.classList.add('copied');
});
}
});
})();

View File

@@ -1,39 +1,60 @@
(() => {
let metadataStore;
const isDev = location.hostname === 'localhost';
const isNext = location.hostname === 'next.shoelace.style';
const customElements = fetch('/dist/custom-elements.json')
.then(res => res.json())
.catch(err => console.error(err));
function createPropsTable(props) {
const table = document.createElement('table');
table.innerHTML = `
<thead>
<tr>
<th>Property</th>
<th>Name</th>
<th>Description</th>
<th>Reflects</th>
<th>Type</th>
<th>Default</th>
</tr>
</thead>
<tbody>
${props
.map(
prop => `
<tr>
<td>
<code>${escapeHtml(prop.name)}</code>
${prop.name !== prop.attr && prop.attr !== undefined ? (`
<br>
<small>
<sl-tooltip content="Use the kebab-case variation in your HTML">
<code class="attribute-tooltip">${escapeHtml(prop.attr)}</code>
</sl-tooltip>
</small>`
) : ''}
</td>
<td>${escapeHtml(prop.docs)}</td>
<td><code style="white-space: normal;">${escapeHtml(prop.type)}</code></td>
<td><code style="white-space: normal;">${escapeHtml(prop.default)}</code></td>
</tr>
`
)
.map(prop => {
const hasAttribute = !!prop.attribute;
const isAttributeDifferent = prop.attribute !== prop.name;
let attributeInfo = '';
if (!hasAttribute) {
attributeInfo = `<br><small>(property only)</small>`;
} else if (isAttributeDifferent) {
attributeInfo = `
<br>
<sl-tooltip content="This attribute is different than the property">
<small>
<code class="nowrap">
${escapeHtml(prop.attribute)}
</code>
</small>
</sl-tooltip>`;
}
return `
<tr>
<td>
<code class="nowrap">${escapeHtml(prop.name)}</code>
${attributeInfo}
</td>
<td>
${escapeHtml(prop.description)}
</td>
<td style="text-align: center;">${
prop.reflects ? '<sl-icon label="yes" name="check"></sl-icon>' : ''
}</td>
<td>${prop.type?.text ? `<code>${escapeHtml(prop.type?.text || '')}</code>` : '-'}</td>
<td>${prop.default ? `<code>${escapeHtml(prop.default)}</code>` : '-'}</td>
</tr>
`;
})
.join('')}
</tbody>
`;
@@ -46,21 +67,21 @@
table.innerHTML = `
<thead>
<tr>
<th>Event</th>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>Event Detail</th>
</tr>
</thead>
<tbody>
${events
.map(
event => `
<tr>
<td><code>${escapeHtml(event.event)}</code></td>
<td>${escapeHtml(event.docs)}</td>
<td><code>CustomEvent&lt;${escapeHtml(event.detail)}&gt;</code></td>
</tr>
`
<tr>
<td><code class="nowrap">${escapeHtml(event.name)}</code></td>
<td>${escapeHtml(event.description)}</td>
<td>${event.type?.text ? `<code>${escapeHtml(event.type?.text)}` : '-'}</td>
</tr>
`
)
.join('')}
</tbody>
@@ -74,21 +95,31 @@
table.innerHTML = `
<thead>
<tr>
<th>Method</th>
<th>Name</th>
<th>Description</th>
<th>Returns</th>
<th>Arguments</th>
</tr>
</thead>
<tbody>
${methods
.map(
method => `
<tr>
<td><code>${escapeHtml(method.name)}</code></td>
<td>${escapeHtml(method.docs)}</td>
<td><code>${escapeHtml(method.returns.type)}</code></td>
</tr>
`
<tr>
<td class="nowrap"><code>${escapeHtml(method.name)}</code></td>
<td>${escapeHtml(method.description)}</td>
<td>
${
method.parameters?.length
? `
<code>${escapeHtml(
method.parameters.map(param => `${param.name}: ${param.type.text}`).join(', ')
)}</code>
`
: '-'
}
</td>
</tr>
`
)
.join('')}
</tbody>
@@ -102,7 +133,7 @@
table.innerHTML = `
<thead>
<tr>
<th>Slot</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
@@ -110,11 +141,11 @@
${slots
.map(
slot => `
<tr>
<td><code>${slot.name ? escapeHtml(slot.name) : '(default)'}</code></td>
<td>${escapeHtml(slot.docs)}</td>
</tr>
`
<tr>
<td class="nowrap">${slot.name ? `<code>${escapeHtml(slot.name)}</code>` : '(default)'}</td>
<td>${escapeHtml(slot.description)}</td>
</tr>
`
)
.join('')}
</tbody>
@@ -136,11 +167,11 @@
${styles
.map(
style => `
<tr>
<td><code>${escapeHtml(style.name)}</code></td>
<td>${escapeHtml(style.docs)}</td>
</tr>
`
<tr>
<td><code>${escapeHtml(style.name)}</code></td>
<td>${escapeHtml(style.description)}</td>
</tr>
`
)
.join('')}
</tbody>
@@ -162,11 +193,11 @@
${parts
.map(
part => `
<tr>
<td><code>${escapeHtml(part.name)}</code></td>
<td>${escapeHtml(part.docs)}</td>
</tr>
`
<tr>
<td class="nowrap"><code>${escapeHtml(part.name)}</code></td>
<td>${escapeHtml(part.description)}</td>
</tr>
`
)
.join('')}
</tbody>
@@ -175,18 +206,58 @@
return table.outerHTML;
}
function createDependentsList(dependents) {
const ul = document.createElement('ul');
ul.innerHTML = `
${dependents
function createAnimationsTable(animations) {
const table = document.createElement('table');
table.innerHTML = `
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
${animations
.map(
dependent => `
<li><code>${escapeHtml(dependent)}</code></li>
animation => `
<tr>
<td class="nowrap"><code>${escapeHtml(animation.name)}</code></td>
<td>${escapeHtml(animation.description)}</td>
</tr>
`
)
.join('')}
</tbody>
`;
return table.outerHTML;
}
function createDependenciesList(targetComponent, allComponents) {
const ul = document.createElement('ul');
const dependencies = [];
// Recursively fetch subdependencies
function getDependencies(tag) {
const component = allComponents.find(c => c.tagName === tag);
if (!component || !Array.isArray(component.dependencies)) {
return [];
}
component.dependencies?.map(tag => {
if (!dependencies.includes(tag)) {
dependencies.push(tag);
}
getDependencies(tag);
});
}
getDependencies(targetComponent);
dependencies.sort().map(tag => {
const li = document.createElement('li');
li.innerHTML = `<code>&lt;${tag}&gt;</code>`;
ul.appendChild(li);
});
return ul.outerHTML;
}
@@ -200,31 +271,24 @@
.replace(/`(.*?)`/g, '<code>$1</code>');
}
function getMetadata() {
return new Promise((resolve, reject) => {
// Simple caching to prevent multiple XHR requests
if (metadataStore) {
return resolve(metadataStore);
}
function getAllComponents(metadata) {
const allComponents = [];
metadata.modules?.map(module => {
module.declarations?.map(declaration => {
if (declaration.customElement) {
// Generate the dist path based on the src path and attach it to the component
declaration.path = module.path.replace(/^src\//, 'dist/').replace(/\.ts$/, '.js');
fetch('/dist/components.json')
.then(res => res.json())
.then(data => {
metadataStore = data;
resolve(metadataStore);
})
.catch(err => console.error(err));
allComponents.push(declaration);
}
});
});
return allComponents;
}
function getDocsTagsObject(docsTags) {
let tags = {};
for (const tag of docsTags) {
tags[tag.name] = tag.text;
}
return tags;
function getComponent(metadata, tagName) {
return getAllComponents(metadata).find(component => component.tagName === tagName);
}
if (!window.$docsify) {
@@ -232,140 +296,195 @@
}
window.$docsify.plugins.push((hook, vm) => {
hook.mounted(function () {
getMetadata().then(metadata => {
const target = document.querySelector('.app-name');
hook.mounted(async function () {
const metadata = await customElements;
const target = document.querySelector('.app-name');
// Add version
const version = document.createElement('div');
version.classList.add('sidebar-version');
version.textContent = metadata.version;
target.appendChild(version);
// Add version
const version = document.createElement('div');
version.classList.add('sidebar-version');
version.textContent = isDev ? 'Development' : isNext ? 'Next' : metadata.package.version;
target.appendChild(version);
// Add repo buttons
const buttons = document.createElement('div');
buttons.classList.add('sidebar-buttons');
buttons.innerHTML = `
<a class="repo-button repo-button--small repo-button--sponsor" href="https://github.com/sponsors/claviska" rel="noopener" target="_blank">
<sl-icon name="heart"></sl-icon> Sponsor
</a>
<a class="repo-button repo-button--small repo-button--github" href="https://github.com/shoelace-style/shoelace/stargazers" rel="noopener" target="_blank">
<sl-icon src="/assets/images/github.svg"></sl-icon> Star
</a>
<a class="repo-button repo-button--small repo-button--twitter" href="https://twitter.com/shoelace_style" rel="noopener" target="_blank">
<sl-icon src="/assets/images/twitter.svg"></sl-icon> Follow
</a>
`;
target.appendChild(buttons);
});
// Store version for reuse
sessionStorage.setItem('sl-version', metadata.package.version);
// Add repo buttons
const buttons = document.createElement('div');
buttons.classList.add('sidebar-buttons');
buttons.innerHTML = `
<sl-button size="small" class="repo-button repo-button--sponsor" href="https://github.com/sponsors/claviska" target="_blank">
<sl-icon name="heart"></sl-icon> Sponsor
</sl-button>
<sl-button size="small" class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace/stargazers" target="_blank">
<sl-icon name="github"></sl-icon> <span class="github-star-count">Star</span>
</sl-button>
<sl-button size="small" class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" target="_blank">
<sl-icon name="twitter"></sl-icon> Follow
</sl-button>
`;
target.appendChild(buttons);
});
hook.beforeEach(async function (content, next) {
const metadata = await getMetadata();
const metadata = await customElements;
// Replace %VERSION% placeholders
content = content.replace(/%VERSION%/g, metadata.version);
content = content.replace(/%VERSION%/g, metadata.package.version);
// Handle [component-header] tags
content = content.replace(/\[component-header:([a-z-]+)\]/g, (match, tag) => {
const data = metadata.components.filter(data => data.tag === tag)[0];
const component = getComponent(metadata, tag);
let result = '';
if (!data) {
if (!component) {
console.error('Component not found in metadata: ' + tag);
next(content);
return next(content);
}
const tags = getDocsTagsObject(data.docsTags);
let badgeType = 'neutral';
if (component.status === 'stable') badgeType = 'primary';
if (component.status === 'experimental') badgeType = 'warning';
if (component.status === 'planned') badgeType = 'neutral';
if (component.status === 'deprecated') badgeType = 'danger';
if (tags && tags.status) {
let badgeType = 'info';
if (tags.status === 'stable') badgeType = 'primary';
if (tags.status === 'experimental') badgeType = 'warning';
if (tags.status === 'planned') badgeType = 'info';
if (tags.status === 'deprecated') badgeType = 'danger';
result += `
<div class="component-header">
<div class="component-header__tag">
<code>&lt;${tag}&gt;</code>
</div>
<div class="component-header__info">
<sl-badge type="info" pill>
Since ${tags.since || '?'}
</sl-badge>
<sl-badge type="${badgeType}" pill style="text-transform: capitalize;">
${tags.status}
</sl-badge>
</div>
result += `
<div class="component-header">
<div class="component-header__tag">
<code>&lt;${component.tagName}&gt; | ${component.name}</code>
</div>
`;
}
<div class="component-header__info">
<sl-badge type="neutral" pill>
Since ${component.since || '?'}
</sl-badge>
<sl-badge type="${badgeType}" pill style="text-transform: capitalize;">
${component.status}
</sl-badge>
</div>
</div>
`;
return result.replace(/^ +| +$/gm, '');
});
// Handle [component-metadata] tags
content = content.replace(/\[component-metadata:([a-z-]+)\]/g, (match, tag) => {
const data = metadata.components.filter(data => data.tag === tag)[0];
const component = getComponent(metadata, tag);
let result = '';
if (!data) {
if (!component) {
console.error('Component not found in metadata: ' + tag);
next(content);
return next(content);
}
if (data.props.length) {
// Remove members that are private or don't have a description
const members = component.members?.filter(member => member.description && member.privacy !== 'private');
const methods = members?.filter(prop => prop.kind === 'method' && prop.privacy !== 'private');
const props = members?.filter(prop => {
// Look for a corresponding attribute
const attribute = component.attributes?.find(attr => attr.fieldName === prop.name);
if (attribute) {
prop.attribute = attribute.name || attribute.fieldName;
}
return prop.kind === 'field' && prop.privacy !== 'private';
});
if (props?.length) {
result += `
## Properties
${createPropsTable(data.props)}
${createPropsTable(props)}
`;
}
if (data.events.length) {
if (component.events?.length) {
result += `
## Events
${createEventsTable(data.events)}
${createEventsTable(component.events)}
`;
}
if (data.methods.length) {
if (methods?.length) {
result += `
## Methods
${createMethodsTable(data.methods)}
## Methods
${createMethodsTable(methods)}
`;
}
if (data.slots.length) {
if (component.slots?.length) {
result += `
## Slots
${createSlotsTable(data.slots)}
${createSlotsTable(component.slots)}
`;
}
if (data.styles.length) {
if (component.cssProperties?.length) {
result += `
## CSS Custom Properties
${createCustomPropertiesTable(data.styles)}
${createCustomPropertiesTable(component.cssProperties)}
`;
}
if (data.parts.length) {
if (component.cssParts?.length) {
result += `
## CSS Parts
${createPartsTable(data.parts)}
${createPartsTable(component.cssParts)}
`;
}
if (data.dependents.length) {
if (component.animations?.length) {
result += `
## Dependents
## Animations
${createAnimationsTable(component.animations)}
The following components make use of this component.
Learn how to [customize animations](/getting-started/customizing#animations).
`;
}
${createDependentsList(data.dependents)}
if (component.dependencies?.length) {
result += `
## Dependencies
This component imports the following dependencies.
${createDependenciesList(component.tagName, getAllComponents(metadata))}
`;
}
if (component.path) {
/* prettier-ignore */
result += `
## Importing
<sl-tab-group>
<sl-tab slot="nav" panel="cdn" active>CDN</sl-tab>
<sl-tab slot="nav" panel="bundler">Bundler</sl-tab>
<sl-tab slot="nav" panel="react">React</sl-tab>
<sl-tab-panel name="cdn">\n
To import this component from [the CDN](https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace):
\`\`\`js
import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${metadata.package.version}/${component.path}';
\`\`\`
</sl-tab-panel>
<sl-tab-panel name="bundler">\n
To import this component using [a bundler](/getting-started/installation#bundling):
\`\`\`js
import '@shoelace-style/shoelace/${component.path}';
\`\`\`
</sl-tab-panel>
<sl-tab-panel name="react">\n
To import this component using [\`@shoelace-style/react\`](https://www.npmjs.com/package/@shoelace-style/react):
\`\`\`js
import '@shoelace-style/react/dist/${component.tagName.replace(/^sl-/, '')}';
\`\`\`
</sl-tab-panel>
</sl-tab-group>
`;
}
@@ -375,5 +494,19 @@
next(content);
});
// Wrap tables so we can scroll them horizontally when needed
hook.doneEach(function () {
const content = document.querySelector('.content');
const tables = [...content.querySelectorAll('table')];
tables.map(table => {
table.outerHTML = `
<div class="table-wrapper">
${table.outerHTML}
</div>
`;
});
});
});
})();

View File

@@ -0,0 +1,24 @@
(() => {
if (!window.$docsify) {
throw new Error('Docsify must be loaded before installing this plugin.');
}
//
// Docsify generates pages dynamically and asynchronously, so when a reload happens, the scroll position can't be
// be restored immediately. This plugin waits until Docsify loads the page and then restores it.
//
window.$docsify.plugins.push((hook, vm) => {
hook.ready(() => {
// Restore
const scrollTop = sessionStorage.getItem('bs-scroll');
if (scrollTop) {
document.documentElement.scrollTop = scrollTop;
}
// Remember
document.addEventListener('scroll', event => {
sessionStorage.setItem('bs-scroll', document.documentElement.scrollTop);
});
});
});
})();

1310
docs/assets/plugins/search/lunr.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,172 @@
body.site-search-visible {
overflow: hidden;
}
.sidebar .search-box {
margin: 1.25rem 26px;
}
.sidebar .search-box kbd {
margin-top: 2px;
}
/* Site search */
.site-search {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
}
.site-search[hidden] {
display: none;
}
.site-search__overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgb(var(--sl-overlay-background-color) / var(--sl-overlay-opacity));
z-index: -1;
}
.site-search__panel {
display: flex;
flex-direction: column;
max-width: 460px;
max-height: calc(100vh - 20rem);
background-color: rgb(var(--sl-surface-base-alt));
border-radius: var(--sl-border-radius-large);
box-shadow: var(--sl-shadow-x-large);
margin: 10rem auto;
}
@media screen and (max-width: 900px) {
.site-search__panel {
max-width: 100%;
max-height: calc(92vh - 120px); /* allow iOS browser chrome */
margin: 4vh var(--sl-spacing-medium);
}
}
.site-search__input::part(base) {
border: none;
background: transparent;
border-radius: var(--sl-border-radius-large);
}
.site-search__input:focus-within::part(base) {
outline: none;
box-shadow: none;
}
.site-search__input {
--sl-input-height-large: 4rem;
}
.site-search__body {
flex: 1 1 auto;
overflow: auto;
}
.site-search--has-results .site-search__body {
border-top: solid 1px rgb(var(--sl-color-neutral-200));
}
.site-search__results {
display: none;
line-height: var(--sl-line-height-dense);
list-style: none;
padding: var(--sl-spacing-x-small) 0;
margin: 0;
}
.site-search--has-results .site-search__results {
display: block;
}
.site-search__results a {
display: block;
text-decoration: none;
padding: var(--sl-spacing-x-small) var(--sl-spacing-large);
}
.site-search__results li a:hover,
.site-search__results li a:hover small {
background-color: rgb(var(--sl-color-neutral-100));
}
.site-search__results li[aria-selected='true'] a,
.site-search__results li[aria-selected='true'] a small,
.site-search__results li[aria-selected='true'] a sl-icon {
outline: none;
color: rgb(var(--sl-color-neutral-0));
background-color: rgb(var(--sl-color-primary-600));
}
.site-search__results h3 {
font-weight: var(--sl-font-weight-semibold);
margin: 0;
}
.site-search__results small {
display: block;
color: rgb(var(--sl-color-neutral-600));
}
.site-search__result {
padding: 0;
margin: 0;
}
.site-search__result a {
display: flex;
align-items: center;
gap: var(--sl-spacing-medium);
}
.site-search__result-icon {
flex: 0 0 auto;
display: flex;
color: rgb(var(--sl-color-neutral-400));
font-size: var(--sl-font-size-x-large);
}
.site-search__result-description {
flex: 1 1 auto;
}
.site-search__empty {
display: none;
border-top: solid 1px rgb(var(--sl-color-neutral-200));
text-align: center;
padding: var(--sl-spacing-x-large);
}
.site-search--no-results .site-search__empty {
display: block;
}
.site-search__footer {
display: flex;
justify-content: center;
gap: var(--sl-spacing-large);
border-top: solid 1px rgb(var(--sl-color-neutral-200));
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
padding: var(--sl-spacing-medium);
}
.site-search__footer small {
color: rgb(var(--sl-color-neutral-700));
}
@media screen and (max-width: 900px) {
.site-search__footer {
display: none;
}
}

View File

@@ -0,0 +1,293 @@
(() => {
if (!window.$docsify) {
throw new Error('Docsify must be loaded before installing this plugin.');
}
window.$docsify.plugins.push((hook, vm) => {
// Append the search box to the sidebar
hook.mounted(function () {
const appName = document.querySelector('.sidebar .app-name');
const searchBox = document.createElement('div');
searchBox.classList.add('search-box');
searchBox.innerHTML = `
<sl-input
type="search"
placeholder="Search"
clearable
pill
>
<sl-icon slot="prefix" name="search"></sl-icon>
<kbd slot="suffix" title="Press / to search">/</kbd>
</sl-input>
`;
const searchBoxInput = searchBox.querySelector('sl-input');
appName.insertAdjacentElement('afterend', searchBox);
// Show the search panel when the search is clicked
searchBoxInput.addEventListener('mousedown', event => {
event.preventDefault();
show();
});
// Show the search panel when a key is pressed
searchBoxInput.addEventListener('keydown', event => {
if (event.key === 'Tab') {
return;
}
// Pass the character that was typed through to the search input
if (event.key.length === 1) {
event.preventDefault();
input.value = event.key;
show();
}
});
});
// Append the search panel to the body
const siteSearch = document.createElement('div');
siteSearch.classList.add('site-search');
siteSearch.hidden = true;
siteSearch.innerHTML = `
<div class="site-search__overlay"></div>
<div class="site-search__panel">
<header class="site-search__header">
<sl-input
class="site-search__input"
type="search"
placeholder="Search this site"
size="large"
clearable
>
<sl-icon slot="prefix" name="search"></sl-icon>
</sl-input>
</header>
<div class="site-search__body">
<ul class="site-search__results"></ul>
<div class="site-search__empty">No results found.</div>
</div>
<footer class="site-search__footer">
<small><kbd>↑</kbd> <kbd>↓</kbd> navigate</small>
<small><kbd>↲</kbd> select</small>
<small><kbd>esc</kbd> close</small>
</footer>
</div>
`;
document.body.append(siteSearch);
const searchButtons = [...document.querySelectorAll('[data-site-search]')];
const overlay = siteSearch.querySelector('.site-search__overlay');
const panel = siteSearch.querySelector('.site-search__panel');
const input = siteSearch.querySelector('.site-search__input');
const results = siteSearch.querySelector('.site-search__results');
const animationDuration = 150;
const searchDebounce = 200;
let isShowing = false;
let searchTimeout;
let searchIndex;
let map;
// Load search data
const searchData = fetch('../../../search.json')
.then(res => res.json())
.then(data => {
searchIndex = lunr.Index.load(data.searchIndex);
map = data.map;
});
async function show() {
isShowing = true;
document.body.classList.add('site-search-visible');
siteSearch.hidden = false;
input.focus();
updateResults();
await Promise.all([
panel.animate(
[
{ opacity: 0, transform: 'scale(.9)' },
{ opacity: 1, transform: 'scale(1)' }
],
{ duration: animationDuration }
).finished,
overlay.animate([{ opacity: 0 }, { opacity: 1 }], { duration: animationDuration }).finished
]);
document.addEventListener('mousedown', handleDocumentMouseDown);
document.addEventListener('keydown', handleDocumentKeyDown);
document.addEventListener('focusin', handleDocumentFocusIn);
}
async function hide() {
isShowing = false;
document.body.classList.remove('site-search-visible');
await Promise.all([
panel.animate(
[
{ opacity: 1, transform: 'scale(1)' },
{ opacity: 0, transform: 'scale(.9)' }
],
{ duration: animationDuration }
).finished,
overlay.animate([{ opacity: 1 }, { opacity: 0 }], { duration: animationDuration }).finished
]);
siteSearch.hidden = true;
input.value = '';
updateResults();
document.removeEventListener('mousedown', handleDocumentMouseDown);
document.removeEventListener('keydown', handleDocumentKeyDown);
document.removeEventListener('focusin', handleDocumentFocusIn);
}
function handleInput() {
// Debounce search queries
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => updateResults(input.value), searchDebounce);
}
function handleDocumentFocusIn(event) {
// Close when focus leaves the panel
if (event.target.closest('.site-search__panel') !== panel) {
hide();
}
}
function handleDocumentMouseDown(event) {
// Close when clicking outside of the panel
if (event.target.closest('.site-search__overlay') === overlay) {
hide();
}
}
function handleDocumentKeyDown(event) {
// Close when pressing escape
if (event.key === 'Escape') {
event.preventDefault();
hide();
return;
}
// Handle keyboard selections
if (['ArrowDown', 'ArrowUp', 'Home', 'End', 'Enter'].includes(event.key)) {
event.preventDefault();
const currentEl = results.querySelector('[aria-selected="true"]');
const items = [...results.querySelectorAll('li')];
const index = items.indexOf(currentEl);
let nextEl;
if (items.length === 0) {
return;
}
switch (event.key) {
case 'ArrowUp':
nextEl = items[Math.max(0, index - 1)];
break;
case 'ArrowDown':
nextEl = items[Math.min(items.length - 1, index + 1)];
break;
case 'Home':
nextEl = items[0];
break;
case 'End':
nextEl = items[items.length - 1];
break;
case 'Enter':
currentEl?.querySelector('a')?.click();
break;
}
// Update the selected item
items.map(item => {
if (item === nextEl) {
item.setAttribute('aria-selected', 'true');
nextEl.scrollIntoView({ block: 'nearest' });
} else {
item.setAttribute('aria-selected', 'false');
}
});
return;
}
}
async function updateResults(query = '') {
try {
await searchIndex;
const hasQuery = query.length > 0;
let matches = hasQuery ? searchIndex.search(`${query}`) : [];
// Fall back to a fuzzy search if no matches are found
if (matches.length === 0 && hasQuery) {
matches = searchIndex.search(`${query}~2`);
}
let hasResults = hasQuery && matches.length > 0;
siteSearch.classList.toggle('site-search--has-results', hasQuery && hasResults);
siteSearch.classList.toggle('site-search--no-results', hasQuery && !hasResults);
panel.setAttribute('aria-expanded', hasQuery && hasResults ? 'true' : 'false');
results.innerHTML = '';
matches.map((match, index) => {
const page = map[match.ref];
const li = document.createElement('li');
const a = document.createElement('a');
let icon = 'file-text';
if (page.url.includes('getting-started/')) icon = 'lightbulb';
if (page.url.includes('resources/')) icon = 'book';
if (page.url.includes('components/')) icon = 'puzzle';
if (page.url.includes('tokens/')) icon = 'palette2';
if (page.url.includes('utilities/')) icon = 'wrench';
if (page.url.includes('tutorials/')) icon = 'joystick';
a.href = $docsify.routerMode === 'hash' ? `/#/${page.url}` : `/${page.url}`;
a.innerHTML = `
<div class="site-search__result-icon">
<sl-icon name="${icon}" aria-hidden="true"></sl-icon>
</div>
<div class="site-search__result__details">
<h3>${page.title}</h3>
<small>${page.url}</small>
</div>
`;
li.classList.add('site-search__result');
li.setAttribute('aria-selected', index === 0 ? 'true' : 'false');
li.appendChild(a);
results.appendChild(li);
});
} catch {
// Ignore query errors as the user types
}
}
// Show the search panel slash is pressed outside of a form element
document.addEventListener('keydown', event => {
if (
!isShowing &&
event.key === '/' &&
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
) {
event.preventDefault();
show();
}
});
input.addEventListener('sl-input', handleInput);
// Close when a result is selected
results.addEventListener('click', event => {
if (event.target.closest('a')) {
hide();
}
});
});
})();

View File

@@ -1,14 +0,0 @@
(() => {
if (!window.$docsify) {
throw new Error('Docsify must be loaded before installing this plugin.');
}
window.$docsify.plugins.push((hook, vm) => {
hook.mounted(function () {
// Move search below the app name
const appName = document.querySelector('.sidebar .app-name');
const search = document.querySelector('.sidebar .search');
appName.insertAdjacentElement("afterend", search);
});
});
})();

View File

@@ -0,0 +1,29 @@
.theme-picker {
position: fixed;
top: 1rem;
right: 1rem;
z-index: 30;
}
.theme-picker:not(:defined) {
display: none;
}
.theme-picker sl-menu-label {
white-space: nowrap;
}
.theme-picker sl-menu-label kbd {
margin-left: 0.5rem;
}
@media screen and (max-width: 768px) {
.theme-picker {
top: 0.5rem;
right: 0.5rem;
}
.theme-picker sl-menu-label {
display: none;
}
}

View File

@@ -0,0 +1,84 @@
(() => {
if (!window.$docsify) {
throw new Error('Docsify must be loaded before installing this plugin.');
}
window.$docsify.plugins.push((hook, vm) => {
hook.mounted(function () {
function getTheme() {
return localStorage.getItem('theme') || 'auto';
}
function isDark() {
if (theme === 'auto') {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
} else {
return theme === 'dark';
}
}
function setTheme(newTheme) {
const noTransitions = Object.assign(document.createElement('style'), {
textContent: '* { transition: none !important; }'
});
theme = newTheme;
localStorage.setItem('theme', theme);
// Update the UI
[...menu.querySelectorAll('sl-menu-item')].map(item => (item.checked = item.getAttribute('value') === theme));
menuIcon.name = isDark() ? 'moon' : 'sun';
// Toggle the dark mode class without transitions
document.body.appendChild(noTransitions);
requestAnimationFrame(() => {
document.documentElement.classList.toggle('sl-theme-dark', isDark());
requestAnimationFrame(() => document.body.removeChild(noTransitions));
});
}
let theme = getTheme();
// Generate the theme picker dropdown
const dropdown = document.createElement('sl-dropdown');
dropdown.classList.add('theme-picker');
dropdown.innerHTML = `
<sl-button size="small" pill slot="trigger" caret>
<sl-icon name="sun" label="Select Theme"></sl-icon>
</sl-button>
<sl-menu>
<sl-menu-label>Toggle <kbd>\\</kbd></sl-menu-label>
<sl-menu-item value="light">Light</sl-menu-item>
<sl-menu-item value="dark">Dark</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item value="auto">Auto</sl-menu-item>
</sl-menu>
`;
document.querySelector('.sidebar-toggle').insertAdjacentElement('afterend', dropdown);
// Listen for selections
const menu = dropdown.querySelector('sl-menu');
const menuIcon = dropdown.querySelector('sl-icon');
menu.addEventListener('sl-select', event => setTheme(event.detail.item.value));
// Update the theme when the preference changes
window.matchMedia('(prefers-color-scheme: dark)').addListener(event => setTheme(theme));
// Toggle themes when pressing backslash
document.addEventListener('keydown', event => {
if (
event.key === '\\' &&
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
) {
event.preventDefault();
setTheme(isDark() ? 'light' : 'dark');
show();
}
});
// Set the intial theme and sync the UI
setTheme(theme);
});
});
})();

View File

@@ -1,52 +0,0 @@
/* Color demo */
.color-demo {
width: 4rem;
height: 2rem;
border-radius: var(--sl-border-radius-small);
box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.33);
}
/* Border radius demo */
.border-radius-demo {
width: 3rem;
height: 3rem;
background: var(--sl-color-primary-50);
}
/* Transition demo */
.transition-demo {
position: relative;
background: var(--sl-color-gray-90);
width: 8rem;
height: 2rem;
}
.transition-demo::after {
content: '';
position: absolute;
background-color: var(--sl-color-primary-50);
top: 0;
left: 0;
width: 0;
height: 100%;
transition-duration: inherit;
transition-property: width;
}
.transition-demo:hover::after {
width: 100%;
}
/* Spacing demo */
.spacing-demo {
width: 100px;
background: var(--sl-color-primary-50);
}
/* Elevation dmeo */
.elevation-demo {
background: var(--sl-color-white);
border-radius: 3px;
width: 4rem;
height: 4rem;
}

View File

@@ -2,7 +2,9 @@ html {
box-sizing: border-box;
}
*, *:before, *:after {
*,
*:before,
*:after {
box-sizing: inherit;
}
@@ -11,12 +13,17 @@ body {
font-size: var(--sl-font-size-medium);
font-weight: var(--sl-font-weight-normal);
letter-spacing: var(--sl-letter-spacing-normal);
color: var(--sl-color-gray-25);
background-color: rgb(var(--sl-surface-base));
color: rgb(var(--sl-color-neutral-800));
line-height: var(--sl-line-height-normal);
}
a {
color: var(--sl-color-primary-50);
color: rgb(var(--sl-color-primary-600));
}
a:hover {
color: rgb(var(--sl-color-primary-700));
}
strong {
@@ -25,22 +32,21 @@ strong {
/* Sidebar */
.sidebar {
background: var(--sl-color-white);
border-right: solid 1px var(--sl-color-gray-95);
background-color: rgb(var(--sl-surface-base));
border-right: solid 1px rgb(var(--sl-color-neutral-200));
}
.sidebar .app-name {
padding: 0 1.5rem;
margin-top: 1.5rem;
}
.sidebar-version {
font-size: var(--sl-font-size-x-small);
font-weight: var(--sl-font-weight-normal);
color: var(--sl-color-gray-60);
color: rgb(var(--sl-color-neutral-500));
text-align: right;
padding: 0 var(--sl-spacing-small);
margin: -1.25rem 0 .6rem 0;
margin: -1.25rem 0 0.6rem 0;
}
.sidebar-buttons {
@@ -48,87 +54,39 @@ strong {
margin-top: 0;
}
/* Search */
.sidebar .search {
position: relative;
border: none;
}
.sidebar .search input[type='search'] {
border: solid 1px var(--sl-input-border-color);
border-radius: var(--sl-border-radius-pill);
padding-left: 1rem;
padding-right: 2rem;
margin: 0 1.25rem;
transition: var(--sl-transition-fast) box-shadow;
}
.sidebar .search input[type='search']:focus {
box-shadow: var(--sl-focus-ring-box-shadow);
border-color: var(--sl-input-border-color-focus);
outline: none;
}
.sidebar .input-wrap {
position: relative;
width: 100%;
padding: 0 .25rem;
}
.sidebar .clear-button {
position: absolute;
right: 30px;
top: 7px;
width: 22px !important;
height: 22px !important;
}
.sidebar .clear-button svg {
transform: scale(.75) !important;
}
.sidebar .clear-button:focus {
outline: none;
}
.search .results-panel {
margin-top: 1rem;
}
.search .matching-post {
border-bottom: solid 1px var(--sl-color-gray-95) !important;
padding: .25rem 1.5rem;
}
.search .matching-post a {
display: block;
border-radius: inherit
padding: .5rem;
}
.search .matching-post h2 {
margin-bottom: 0;
}
.search .matching-post p {
margin-top: 0;
}
/* Sidebar toggle */
.sidebar-toggle {
top: .25rem;
left: .25rem;
top: 0.25rem;
left: 0.25rem;
width: 2rem;
height: 2rem;
border-radius: var(--sl-border-radius-medium);
padding: .5rem;
background-color: rgb(var(--sl-surface-base));
padding: 0.5rem;
}
.sidebar-toggle:hover .sidebar-toggle-button {
opacity: 1;
}
.sidebar-toggle:active .sidebar-toggle-button span {
background-color: rgb(var(--sl-color-primary-600));
}
.sidebar-toggle:focus {
outline: none;
box-shadow: var(--sl-focus-ring);
}
.sidebar-toggle span:last-child {
margin-bottom: 0;
}
@media screen and (max-width: 768px) {
body.close .sidebar-toggle {
width: 2rem;
background: none;
padding: .5rem;
padding: 0.5rem;
}
}
@@ -137,33 +95,40 @@ strong {
padding: 0 1rem;
}
.sidebar-nav li {
line-height: 1;
padding: 0;
}
.sidebar-nav a {
color: inherit;
text-decoration: none;
line-height: 1.5em;
padding-top: 0.25em;
padding-bottom: 0.25em;
}
.sidebar-nav li.collapse > a,
.sidebar-nav li.active > a {
color: var(--sl-color-primary-50);
color: rgb(var(--sl-color-primary-600));
}
.sidebar li > p {
font-weight: var(--sl-font-weight-bold);
border-bottom: solid 1px var(--sl-color-gray-90);
margin: 0 .75rem .5rem 0;
border-bottom: solid 1px rgb(var(--sl-color-neutral-200));
margin: 0 0.75rem 0.5rem 0;
}
.sidebar ul li ul {
padding-left: .5rem;
margin: 0 .75rem 1.5rem 0;
padding-left: 0.5rem;
margin: 0 0.75rem 1.5rem 0;
}
.sidebar ul ul ul {
padding: 0;
margin: 0 0 0 .5rem;
margin: 0 0 0 0.5rem;
}
.sidebar ul ul ul li {
list-style: disc;
margin-left: 1.5rem;
@@ -172,7 +137,7 @@ strong {
/* Splash */
.splash {
display: flex;
padding: 2rem 0;
padding-top: 2rem;
}
.splash-start {
@@ -195,6 +160,11 @@ strong {
max-width: 22rem;
}
.markdown-section .splash-start h1:first-of-type {
font-size: var(--sl-font-size-large);
margin: 0 0 0.5rem 0;
}
@media screen and (max-width: 1040px) {
.splash {
display: block;
@@ -213,6 +183,11 @@ strong {
display: block;
max-width: 400px;
}
/* Shields */
.splash + p {
margin-top: 2rem;
}
}
/* Content */
@@ -222,11 +197,16 @@ strong {
.markdown-section {
max-width: 860px;
overflow-anchor: none;
}
.anchor span {
color: rgb(var(--sl-color-neutral-1000));
}
.markdown-section blockquote {
position: relative;
border-left: solid 4px var(--sl-color-gray-90);
border-left: solid 4px rgb(var(--sl-color-neutral-200));
font-style: italic;
padding: 1rem 1.5rem;
margin: 0 0 1rem 0;
@@ -242,11 +222,21 @@ strong {
.markdown-section ul {
padding: 0 0 0 1.5rem;
margin: 0;
margin: 0 0 1rem 0;
}
.markdown-section .anchor {
color: var(--sl-color-primary-50);
.markdown-section ul ul {
margin-bottom: 0;
}
.docsify-pagination-container {
border-top-color: rgb(var(--sl-color-neutral-200)) !important;
}
.pagination-item-label,
.pagination-item-subtitle,
.pagination-item-title {
opacity: 1 !important;
}
.markdown-section h1,
@@ -260,12 +250,12 @@ strong {
}
.markdown-section h1 {
font-size: var(--sl-font-size-xx-large);
font-size: var(--sl-font-size-2x-large);
}
.markdown-section h2 {
font-size: var(--sl-font-size-x-large);
border-bottom: solid 1px var(--sl-color-gray-90);
border-bottom: solid 1px rgb(var(--sl-color-neutral-200));
margin-top: 2rem;
}
@@ -296,22 +286,38 @@ strong {
.markdown-section code {
font-family: var(--sl-font-mono);
font-size: 87.5%;
background: hsla(var(--sl-color-gray-hue), var(--sl-color-gray-saturation), 50%, .05);
background-color: rgb(var(--sl-color-neutral-50));
border-radius: var(--sl-border-radius-small);
padding: 2px 4px;
}
.markdown-section tr:nth-child(2n) code {
background-color: rgb(var(--sl-color-neutral-100));
}
kbd,
.markdown-section kbd {
font-family: var(--sl-font-mono);
font-size: 87.5%;
background-color: rgb(var(--sl-color-neutral-50));
border-radius: var(--sl-border-radius-small);
border: solid 1px rgb(var(--sl-color-neutral-200));
box-shadow: inset 0 1px 0 rgb(var(--sl-color-neutral-0));
padding: 2px 5px;
}
/* Code blocks */
.markdown-section pre {
position: relative;
background: hsl(var(--sl-color-gray-hue), var(--sl-color-gray-saturation), 97%);
background-color: rgb(var(--sl-color-neutral-50));
border-radius: var(--sl-border-radius-medium);
}
.markdown-section pre > code {
display: block;
background: none;
color: var(--sl-color-gray-30);
border-radius: 0;
color: rgb(var(--sl-color-neutral-800));
padding: var(--sl-spacing-medium);
overflow: auto;
hyphens: none;
@@ -319,34 +325,34 @@ strong {
}
.markdown-section pre .token.comment {
color: var(--sl-color-gray-70);
color: rgb(var(--sl-color-neutral-500));
}
.markdown-section pre .token.prolog,
.markdown-section pre .token.doctype,
.markdown-section pre .token.cdata,
.markdown-section pre .token.operator {
color: var(--sl-color-gray-40);
color: rgb(var(--sl-color-neutral-600));
}
.markdown-section pre .token.punctuation {
color: var(--sl-color-gray-50);
color: rgb(var(--sl-color-neutral-600));
}
.namespace {
opacity: .7;
opacity: 0.7;
}
.markdown-section pre .token.property,
.markdown-section pre .token.keyword,
.markdown-section pre .token.tag,
.markdown-section pre .token.url {
color: var(--sl-color-primary-45);
color: rgb(var(--sl-color-sky-600));
}
.markdown-section pre .token.symbol,
.markdown-section pre .token.deleted {
color: #f92672;
color: rgb(var(--sl-color-pink-600));
}
.markdown-section pre .token.boolean,
@@ -357,27 +363,24 @@ strong {
.markdown-section pre .token.char,
.markdown-section pre .token.builtin,
.markdown-section pre .token.inserted {
color: var(--sl-color-success-40);
color: rgb(var(--sl-color-emerald-600));
}
.markdown-section pre .token.atrule,
.markdown-section pre .token.attr-value,
.markdown-section pre .token.number,
.markdown-section pre .token.variable {
color: #9013fe;
color: rgb(var(--sl-color-violet-600));
}
.markdown-section pre .token.function,
.markdown-section pre .token.class-name {
color: #eb9200;
}
.markdown-section pre .token.class-name,
.markdown-section pre .token.regex {
color: #f5a623;
color: rgb(var(--sl-color-orange-600));
}
.markdown-section pre .token.important {
color: #d0021b;
color: rgb(var(--sl-color-red-600));
}
.markdown-section pre .token.important,
@@ -390,7 +393,18 @@ strong {
}
/* Tables */
.table-wrapper {
overflow-x: auto;
}
@media screen and (max-width: 1200px) {
.table-wrapper table {
min-width: 800px;
}
}
.markdown-section table {
display: table;
margin-bottom: 1.5rem;
}
@@ -399,37 +413,41 @@ strong {
}
.markdown-section tr:nth-child(2n) {
background: hsl(var(--sl-color-gray-hue), var(--sl-color-gray-saturation), 97%);
background: rgb(var(--sl-color-neutral-50));
}
.markdown-section th {
border: none;
font-weight: inherit;
font-weight: var(--sl-font-weight-semibold);
text-align: left;
}
.markdown-section td {
border-top: solid 1px var(--sl-color-gray-90);
border-bottom: solid 1px var(--sl-color-gray-90);
border-top: solid 1px rgb(var(--sl-color-neutral-200));
border-bottom: solid 1px rgb(var(--sl-color-neutral-200));
border-left: none;
border-right: none;
}
.markdown-section td code {
.markdown-section table .nowrap {
white-space: nowrap;
}
.markdown-section table .attribute-tooltip {
background: none;
border-bottom: dashed 1px var(--sl-color-gray-80);
.markdown-section table sl-tooltip code {
border-bottom: dashed 1px rgb(var(--sl-color-neutral-300));
cursor: help;
}
/* Iframes */
.markdown-section iframe {
border: none;
}
/* Tips & Warnings */
.markdown-section p.tip,
.markdown-section p.warn {
position: relative;
background: hsl(var(--sl-color-gray-hue), var(--sl-color-gray-saturation), 97%);
background-color: rgb(var(--sl-color-neutral-50));
border-left: solid 4px transparent;
border-radius: var(--sl-border-radius-medium);
padding-left: 1.5rem;
@@ -439,7 +457,7 @@ strong {
.markdown-section p.warn:before {
content: '!';
border-radius: 100%;
color: var(--sl-color-white);
color: rgb(var(--sl-color-neutral-0));
font-size: 14px;
font-weight: bold;
left: -12px;
@@ -452,24 +470,29 @@ strong {
}
.markdown-section p.warn {
border-left-color: var(--sl-color-primary-50);
border-left-color: rgb(var(--sl-color-primary-600));
}
.markdown-section p.warn:before {
background-color: var(--sl-color-primary-50);
background-color: rgb(var(--sl-color-primary-600));
}
.markdown-section p.tip {
border-left-color: var(--sl-color-danger-50);
border-left-color: rgb(var(--sl-color-danger-600));
}
.markdown-section p.tip:before {
background-color: var(--sl-color-danger-50);
background-color: rgb(var(--sl-color-danger-600));
}
.markdown-section p.tip code,
.markdown-section p.warn code {
background-color: rgb(var(--sl-color-neutral-100));
}
/* Component headers */
.component-header {
border-bottom: solid 1px var(--sl-color-gray-90);
border-bottom: solid 1px rgb(var(--sl-color-neutral-200));
padding-bottom: 2rem;
margin-top: -1rem;
margin-bottom: 2rem;
@@ -481,9 +504,9 @@ strong {
margin: 0.75rem 0 0.25rem 0;
}
.component-header__tag code {
.markdown-section .component-header__tag code {
background: none;
color: var(--sl-color-gray-50);
color: rgb(var(--sl-color-neutral-600));
font-size: var(--sl-font-size-large);
padding: 0;
margin: 0;
@@ -499,71 +522,122 @@ strong {
line-height: 1.6;
}
/* Copy button */
.docsify-copy-code-button {
font-size: var(--sl-font-size-small) !important;
border-top-right-radius: var(--sl-border-radius-medium) !important;
border-bottom-left-radius: var(--sl-border-radius-medium) !important;
}
/* Repo buttons */
html .repo-button {
display: inline-block;
vertical-align: middle;
background-color: var(--sl-color-white);
border: solid 1px var(--sl-color-gray-85);
border-radius: var(--sl-border-radius-medium);
box-shadow: var(--sl-shadow-x-small);
font-size: var(--sl-font-size-small);
font-weight: var(--sl-font-weight-semibold);
text-decoration: none;
color: var(--sl-color-gray-30);
padding: var(--sl-spacing-xx-small) var(--sl-spacing-small);
margin-bottom: var(--sl-spacing-xx-small);
transition: 0.25s all;
.repo-button--sponsor sl-icon {
color: rgb(var(--sl-color-pink-600));
}
html .repo-button:hover {
text-decoration: none;
background-color: var(--sl-color-gray-95);
border: solid 1px var(--sl-color-gray-80);
.repo-button--github sl-icon {
color: rgb(var(--sl-color-neutral-700));
}
html .repo-button:focus {
outline: none;
border-color: var(--sl-color-primary-50);
box-shadow: var(--sl-focus-ring-box-shadow);
.repo-button--twitter sl-icon {
color: rgb(var(--sl-color-sky-500));
}
html .repo-button:not(:last-of-type) {
margin-right: .125rem;
@media screen and (max-width: 400px) {
:not(.sidebar-buttons) > .repo-button {
width: 100%;
margin-bottom: 1rem;
}
}
html .repo-button sl-icon {
position: relative;
top: -1px;
vertical-align: middle;
margin-right: 0.125rem;
}
html .repo-button--small {
font-size: var(--sl-font-size-x-small);
padding: var(--sl-spacing-xxx-small) var(--sl-spacing-x-small);
}
html .repo-button--sponsor sl-icon {
color: #ea4aaa;
}
html .repo-button--github sl-icon {
color: #242a2e;
}
html .repo-button--twitter sl-icon {
color: #1ea0f2;
}
body[data-page^="tokens/"] .table-wrapper td:first-child,
body[data-page^="tokens/"] .table-wrapper td:first-child code {
body[data-page^='/tokens/'] .table-wrapper td:first-child,
body[data-page^='/tokens/'] .table-wrapper td:first-child code {
white-space: nowrap;
}
/* Border radius demo */
.border-radius-demo {
width: 3rem;
height: 3rem;
background: rgb(var(--sl-color-primary-600));
}
/* Transition demo */
.transition-demo {
position: relative;
background: rgb(var(--sl-color-neutral-200));
width: 8rem;
height: 2rem;
}
.transition-demo:after {
content: '';
position: absolute;
background-color: rgb(var(--sl-color-primary-600));
top: 0;
left: 0;
width: 0;
height: 100%;
transition-duration: inherit;
transition-property: width;
}
.transition-demo:hover:after {
width: 100%;
}
/* Spacing demo */
.spacing-demo {
width: 100px;
background: rgb(var(--sl-color-primary-600));
}
/* Elevation dmeo */
.elevation-demo {
background: transparent;
border-radius: 3px;
width: 4rem;
height: 4rem;
margin: 1rem;
}
/* Color palettes */
.color-palette {
display: grid;
grid-template-columns: 200px repeat(11, 1fr);
gap: 1rem var(--sl-spacing-2x-small);
margin: 2rem 0;
}
.color-palette__name {
font-size: var(--sl-font-size-medium);
font-weight: var(--sl-font-weight-semibold);
grid-template-columns: repeat(11, 1fr);
}
.color-palette__name code {
background: none;
font-size: var(--sl-font-size-x-small);
}
.color-palette__example {
font-size: var(--sl-font-size-x-small);
text-align: center;
}
.color-palette__swatch {
height: 3rem;
border-radius: var(--sl-border-radius-small);
}
.color-palette__swatch--border {
box-shadow: inset 0 0 0 1px rgb(var(--sl-color-neutral-1000) / 10%);
}
@media screen and (max-width: 1200px) {
.color-palette {
grid-template-columns: repeat(6, 1fr);
}
.color-palette__name {
grid-column-start: span 6;
}
}
.not-found-image {
display: block;
max-width: 460px;
margin: 2rem 0;
}

View File

@@ -2,9 +2,7 @@
[component-header:sl-alert]
Alerts are used to display important messages.
Alerts are designed to be shown dynamically, so you need to include the `open` attribute to display them.
Alerts are used to display important messages either inline or as toast notifications.
```html preview
<sl-alert open>
@@ -13,6 +11,8 @@ Alerts are designed to be shown dynamically, so you need to include the `open` a
</sl-alert>
```
?> Alerts will not be visible if the `open` attribute is not present.
## Examples
### Types
@@ -36,26 +36,26 @@ Set the `type` attribute to change the alert's type.
<br>
<sl-alert type="info" open>
<sl-alert type="neutral" open>
<sl-icon slot="icon" name="gear"></sl-icon>
<strong>Your settings have been updated</strong><br>
Some settings will take affect the next time you log in.
Settings will take affect on next login.
</sl-alert>
<br>
<sl-alert type="warning" open>
<sl-icon slot="icon" name="exclamation-triangle"></sl-icon>
<strong>This will end your session</strong><br>
You will be logged out until you log in again.
<strong>Your session has ended</strong><br>
Please login again to continue.
</sl-alert>
<br>
<sl-alert type="danger" open>
<sl-icon slot="icon" name="exclamation-octagon"></sl-icon>
<strong>Delete this file?</strong><br>
This is permanent, which means forever!
<strong>Your account has been deleted</strong><br>
We're very sorry to see you go!
</sl-alert>
```
@@ -71,7 +71,7 @@ Add the `closable` attribute to show a close button that will hide the alert.
<script>
const alert = document.querySelector('.alert-closable');
alert.addEventListener('slAfterHide', () => {
alert.addEventListener('sl-after-hide', () => {
setTimeout(() => alert.open = true, 2000);
});
</script>
@@ -87,4 +87,148 @@ Icons are optional. Simply omit the `icon` slot if you don't want them.
</sl-alert>
```
### Duration
Set the `duration` attribute to automatically hide an alert after a period of time. This is useful for alerts that don't require acknowledgement.
```html preview
<div class="alert-duration">
<sl-button type="primary">Show Alert</sl-button>
<sl-alert type="primary" duration="3000" closable>
<sl-icon slot="icon" name="info-circle"></sl-icon>
This alert will automatically hide itself after three seconds, unless you interact with it.
</sl-alert>
</div>
<script>
const container = document.querySelector('.alert-duration');
const button = container.querySelector('sl-button');
const alert = container.querySelector('sl-alert');
button.addEventListener('click', () => alert.show());
</script>
<style>
.alert-duration sl-alert {
margin-top: var(--sl-spacing-medium);
}
</style>
```
### Toast Notifications
To display an alert as a toast notification, or "toast", create the alert and call its `toast()` method. This will move the alert out of its position in the DOM and into [the toast stack](#the-toast-stack) where it will be shown. Once dismissed, it will be removed from the DOM completely. To reuse a toast, store a reference to it and call `toast()` again later on.
You should always use the `closable` attribute so users can dismiss the notification. It's also common to set a reasonable `duration` when the notification doesn't require acknowledgement.
```html preview
<div class="alert-toast">
<sl-button type="primary">Primary</sl-button>
<sl-button type="success">Success</sl-button>
<sl-button type="neutral">Neutral</sl-button>
<sl-button type="warning">Warning</sl-button>
<sl-button type="danger">Danger</sl-button>
<sl-alert type="primary" duration="3000" closable>
<sl-icon slot="icon" name="info-circle"></sl-icon>
<strong>This is super informative</strong><br>
You can tell by how pretty the alert is.
</sl-alert>
<sl-alert type="success" duration="3000" closable>
<sl-icon slot="icon" name="check2-circle"></sl-icon>
<strong>Your changes have been saved</strong><br>
You can safely exit the app now.
</sl-alert>
<sl-alert type="neutral" duration="3000" closable>
<sl-icon slot="icon" name="gear"></sl-icon>
<strong>Your settings have been updated</strong><br>
Settings will take affect on next login.
</sl-alert>
<sl-alert type="warning" duration="3000" closable>
<sl-icon slot="icon" name="exclamation-triangle"></sl-icon>
<strong>Your session has ended</strong><br>
Please login again to continue.
</sl-alert>
<sl-alert type="danger" duration="3000" closable>
<sl-icon slot="icon" name="exclamation-octagon"></sl-icon>
<strong>Your account has been deleted</strong><br>
We're very sorry to see you go!
</sl-alert>
</div>
<script>
const container = document.querySelector('.alert-toast');
['primary', 'success', 'neutral', 'warning', 'danger'].map(type => {
const button = container.querySelector(`sl-button[type="${type}"]`);
const alert = container.querySelector(`sl-alert[type="${type}"]`);
button.addEventListener('click', () => alert.toast());
});
</script>
```
### Creating Toasts Imperatively
For convenience, you can create a utility that emits toast notifications with a function call rather than composing them in your HTML. To do this, generate the alert with JavaScript, append it to the body, and call the `toast()` method as shown in the example below.
```html preview
<div class="alert-toast-wrapper">
<sl-button type="primary">Create Toast</sl-button>
</div>
<script>
const container = document.querySelector('.alert-toast-wrapper');
const button = container.querySelector('sl-button');
let count = 0;
// Always escape HTML for text arguments!
function escapeHtml(html) {
const div = document.createElement('div');
div.textContent = html;
return div.innerHTML;
}
// Custom function to emit toast notifications
function notify(message, type = 'primary', icon = 'info-circle', duration = 3000) {
const alert = Object.assign(document.createElement('sl-alert'), {
type: type,
closable: true,
duration: duration,
innerHTML: `
<sl-icon name="${icon}" slot="icon"></sl-icon>
${escapeHtml(message)}
`
});
document.body.append(alert);
return alert.toast();
}
button.addEventListener('click', () => {
notify(`This is custom toast #${++count}`);
});
</script>
```
### The Toast Stack
The toast stack is a fixed position singleton element created and managed internally by the alert component. It will be added and removed from the DOM as needed when toasts are shown. When more than one toast is visible, they will stack vertically in the toast stack.
By default, the toast stack is positioned at the top-right of the viewport. You can change its position by targeting `.sl-toast-stack` in your stylesheet. To make toasts appear at the top-left of the viewport, for example, use the following styles.
```css
.sl-toast-stack {
left: 0;
right: auto;
}
```
?> By design, it is not possible to show toasts in more than one stack simultaneously. Such behavior is confusing and makes for a poor user experience.
[component-metadata:sl-alert]

View File

@@ -0,0 +1,63 @@
# Animated Image
[component-header:sl-animated-image]
A component for displaying animated GIFs and WEBPs that play and pause on interaction.
```html preview
<sl-animated-image
src="/assets/images/walk.gif"
alt="Animation of untied shoes walking on pavement"
></sl-animated-image>
```
## Examples
### WEBP Images
Both GIF and WEBP images are supported.
```html preview
<sl-animated-image
src="/assets/images/tie.webp"
alt="Animation of a shoe being tied"
></sl-animated-image>
```
### Setting a Width and Height
To set a custom size, apply a width and/or height to the host element.
```html preview
<sl-animated-image
src="/assets/images/walk.gif"
alt="Animation of untied shoes walking on pavement"
style="width: 150px; height: 200px;"
>
</sl-animated-image>
```
### Customizing the Control Box
You can change the appearance and location of the control box by targeting the `control-box` part in your styles.
```html preview
<sl-animated-image
src="/assets/images/walk.gif"
alt="Animation of untied shoes walking on pavement"
class="animated-image-custom-control-box"
></sl-animated-image>
<style>
.animated-image-custom-control-box::part(control-box) {
top: auto;
right: auto;
bottom: 1rem;
left: 1rem;
background-color: deeppink;
color: white;
}
</style>
```
[component-metadata:sl-animated-image]

View File

@@ -0,0 +1,199 @@
# Animation
[component-header:sl-animation]
Animate elements declaratively with nearly 100 baked-in presets, or roll your own with custom keyframes. Powered by the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
To animate an element, wrap it in `<sl-animation>` and set an animation `name`. The animation not start until you add the `play` attribute. Refer to the [properties table](#properties) for a list of all animation options.
```html preview
<div class="animation-overview">
<sl-animation name="bounce" duration="2000" play><div class="box"></div></sl-animation>
<sl-animation name="jello" duration="2000" play><div class="box"></div></sl-animation>
<sl-animation name="heartBeat" duration="2000" play><div class="box"></div></sl-animation>
<sl-animation name="flip" duration="2000" play><div class="box"></div></sl-animation>
</div>
<style>
.animation-overview .box {
display: inline-block;
width: 100px;
height: 100px;
background-color: rgb(var(--sl-color-primary-600));
margin: 1.5rem;
}
</style>
```
?> The animation will only be applied to the first child element found in `<sl-animation>`.
## Examples
### Animations & Easings
This example demonstrates all of the baked-in animations and easings. Animations are based on those found in the popular [Animate.css](https://animate.style/) library.
```html preview
<div class="animation-sandbox">
<sl-animation name="bounce" easing="ease-in-out" duration="2000" play>
<div class="box"></div>
</sl-animation>
<div class="controls">
<sl-select label="Animation" value="bounce"></sl-select>
<sl-select label="Easing" value="linear"></sl-select>
<sl-range min="0" max="2" step=".5" value="1"></sl-range>
</div>
</div>
<script type="module">
import { getAnimationNames, getEasingNames } from '/dist/utilities/animation.js';
const container = document.querySelector('.animation-sandbox');
const animation = container.querySelector('sl-animation');
const animationName = container.querySelector('.controls sl-select:nth-child(1)');
const easingName = container.querySelector('.controls sl-select:nth-child(2)');
const playbackRate = container.querySelector('sl-range');
const animations = getAnimationNames();
const easings = getEasingNames();
animations.map(name => {
const menuItem = Object.assign(document.createElement('sl-menu-item'), {
textContent: name,
value: name
});
animationName.appendChild(menuItem);
});
easings.map(name => {
const menuItem = Object.assign(document.createElement('sl-menu-item'), {
textContent: name,
value: name
});
easingName.appendChild(menuItem);
});
animationName.addEventListener('sl-change', () => animation.name = animationName.value);
easingName.addEventListener('sl-change', () => animation.easing = easingName.value);
playbackRate.addEventListener('sl-change', () => animation.playbackRate = playbackRate.value);
playbackRate.tooltipFormatter = val => `Playback Rate = ${val}`;
</script>
<style>
.animation-sandbox .box {
width: 100px;
height: 100px;
background-color: rgb(var(--sl-color-primary-600));
}
.animation-sandbox .controls {
max-width: 300px;
margin-top: 2rem;
}
.animation-sandbox .controls sl-select {
margin-bottom: 1rem;
}
</style>
```
### Using Intersection Observer
Use an [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) to control the animation when an element enters or exits the viewport. For example, scroll the box below in and out of your screen. The animation stops when the box exits the viewport and restarts each time it enters the viewport.
```html preview
<div class="animation-scroll">
<sl-animation name="jackInTheBox" duration="2000" iterations="1"><div class="box"></div></sl-animation>
</div>
<script>
const container = document.querySelector('.animation-scroll');
const animation = container.querySelector('sl-animation');
const box = animation.querySelector('.box');
// Watch for the box to enter and exit the viewport. Note that we're observing the box, not the animation element!
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
// Start the animation when the box enters the viewport
animation.play = true;
} else {
animation.play = false;
animation.currentTime = 0;
}
});
observer.observe(box);
</script>
<style>
.animation-scroll .box {
display: inline-block;
width: 100px;
height: 100px;
background-color: rgb(var(--sl-color-primary-600));
}
</style>
```
### Custom Keyframe Formats
Supply your own [keyframe formats](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Keyframe_Formats) to build custom animations.
```html preview
<div class="animation-keyframes">
<sl-animation easing="ease-in-out" duration="2000" play>
<div class="box"></div>
</sl-animation>
</div>
<script>
const animation = document.querySelector('.animation-keyframes sl-animation');
animation.keyframes = [
{
offset: 0,
easing: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
fillMode: 'both',
transformOrigin: 'center center',
transform: 'rotate(0)'
},
{
offset: 1,
easing: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
fillMode: 'both',
transformOrigin: 'center center',
transform: 'rotate(90deg)'
}
];
</script>
<style>
.animation-keyframes .box {
width: 100px;
height: 100px;
background-color: rgb(var(--sl-color-primary-600));
}
</style>
```
### Playing Animations on Demand
Animations won't play until you apply the `play` attribute. You can omit it initially, then apply it on demand such as after a user interaction. In this example, the button will animate once every time the button is clicked.
```html preview
<div class="animation-form">
<sl-animation name="rubberBand" duration="1000" iterations="1">
<sl-button type="primary">Click me</sl-button>
</sl-animation>
</div>
<script>
const container = document.querySelector('.animation-form');
const animation = container.querySelector('sl-animation');
const button = container.querySelector('sl-button');
button.addEventListener('click', () => {
animation.play = true;
});
</script>
```
[component-metadata:sl-animation]

View File

@@ -59,4 +59,28 @@ Avatars can be shaped using the `shape` attribute.
<sl-avatar shape="circle"></sl-avatar>
```
### Avatar Groups
You can group avatars with a few lines of CSS.
```html preview
<div class="avatar-group">
<sl-avatar image="https://images.unsplash.com/photo-1490150028299-bf57d78394e0?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&q=80&crop=right"></sl-avatar>
<sl-avatar image="https://images.unsplash.com/photo-1503454537195-1dcabb73ffb9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&crop=left&q=80"></sl-avatar>
<sl-avatar image="https://images.unsplash.com/photo-1456439663599-95b042d50252?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&crop=left&q=80"></sl-avatar>
<sl-avatar image="https://images.unsplash.com/flagged/photo-1554078875-e37cb8b0e27d?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&crop=top&q=80"></sl-avatar>
</div>
<style>
.avatar-group sl-avatar:not(:first-of-type) {
margin-left: -1rem;
}
.avatar-group sl-avatar::part(base) {
border: solid 2px rgb(var(--sl-color-neutral-0));
}
</style>
```
[component-metadata:sl-avatar]

View File

@@ -5,7 +5,7 @@
Badges are used to draw attention and display statuses or counts.
```html preview
<sl-badge>Badge</sl-icon></sl-badge>
<sl-badge>Badge</sl-badge>
```
## Examples
@@ -15,23 +15,45 @@ Badges are used to draw attention and display statuses or counts.
Set the `type` attribute to change the badge's type.
```html preview
<sl-badge type="primary">Primary</sl-icon></sl-badge>
<sl-badge type="primary">Primary</sl-badge>
<sl-badge type="success">Success</sl-badge>
<sl-badge type="info">Info</sl-badge>
<sl-badge type="neutral">Neutral</sl-badge>
<sl-badge type="warning">Warning</sl-badge>
<sl-badge type="danger">Danger</sl-badge>
```
### Pill Badges
Use the `pill` attribute to give badges rounded edges.
```html preview
<sl-badge type="primary" pill>Primary</sl-icon></sl-badge>
<sl-badge type="primary" pill>Primary</sl-badge>
<sl-badge type="success" pill>Success</sl-badge>
<sl-badge type="info" pill>Info</sl-badge>
<sl-badge type="neutral" pill>Neutral</sl-badge>
<sl-badge type="warning" pill>Warning</sl-badge>
<sl-badge type="danger" pill>Danger</sl-badge>
```
### Pulsating Badges
Use the `pulse` attribute to draw attention to the badge with a subtle animation.
```html preview
<div class="badge-pulse">
<sl-badge type="primary" pill pulse>1</sl-badge>
<sl-badge type="success" pill pulse>1</sl-badge>
<sl-badge type="neutral" pill pulse>1</sl-badge>
<sl-badge type="warning" pill pulse>1</sl-badge>
<sl-badge type="danger" pill pulse>1</sl-badge>
</div>
<style>
.badge-pulse sl-badge:not(:last-of-type) {
margin-right: 1rem;
}
</style>
```
### With Buttons
One of the most common use cases for badges is attaching them to buttons. To make this easier, badges will be automatically positioned at the top-right when they're a child of a button.
@@ -58,12 +80,10 @@ One of the most common use cases for badges is attaching them to buttons. To mak
When including badges in menu items, use the `suffix` slot to make sure they're aligned correctly.
```html preview
<sl-menu
style="max-width: 240px; border: solid 1px var(--sl-color-gray-90); border-radius: var(--sl-border-radius-medium);"
>
<sl-menu style="max-width: 240px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-label>Messages</sl-menu-label>
<sl-menu-item>Comments <sl-badge slot="suffix" pill>4</sl-badge></sl-menu-item>
<sl-menu-item>Replies <sl-badge slot="suffix" pill>12</sl-badge></sl-menu-item>
<sl-menu-item>Comments <sl-badge slot="suffix" type="neutral" pill>4</sl-badge></sl-menu-item>
<sl-menu-item>Replies <sl-badge slot="suffix" type="neutral" pill>12</sl-badge></sl-menu-item>
</sl-menu>
```

View File

@@ -0,0 +1,20 @@
# Breadcrumb Item
[component-header:sl-breadcrumb-item]
Breadcrumb Items are used inside [breadcrumbs](/components/breadcrumb) to represent different links.
```html preview
<sl-breadcrumb>
<sl-breadcrumb-item>
<sl-icon slot="prefix" name="house"></sl-icon>
Home
</sl-breadcrumb-item>
<sl-breadcrumb-item>Clothing</sl-breadcrumb-item>
<sl-breadcrumb-item>Shirts</sl-breadcrumb-item>
</sl-breadcrumb>
```
?> Additional demonstrations can be found in the [breadcrumb examples](/components/breadcrumb).
[component-metadata:sl-breadcrumb-item]

View File

@@ -0,0 +1,132 @@
# Breadcrumb
[component-header:sl-breadcrumb]
Breadcrumbs provide a group of links so users can easily navigate a website's hierarchy.
Breadcrumbs are usually placed before a page's main content with the current page shown last to indicate the user's position in the navigation.
```html preview
<sl-breadcrumb>
<sl-breadcrumb-item>Catalog</sl-breadcrumb-item>
<sl-breadcrumb-item>Clothing</sl-breadcrumb-item>
<sl-breadcrumb-item>Women's</sl-breadcrumb-item>
<sl-breadcrumb-item>Shirts &amp; Tops</sl-breadcrumb-item>
</sl-breadcrumb>
```
## Examples
### Breadcrumb Links
By default, breadcrumb items are rendered as buttons so you can use them to navigate single-page applications. In this case, you'll need to add event listeners to handle clicks.
For websites, you'll probably want to use links instead. You can make any breadcrumb item a link by applying an `href` attribute to it. Now, when the user activates it, they'll be taken to the corresponding page — no event listeners required.
```html preview
<sl-breadcrumb>
<sl-breadcrumb-item href="https://example.com/home">
Homepage
</sl-breadcrumb-item>
<sl-breadcrumb-item href="https://example.com/home/services">
Our Services
</sl-breadcrumb-item>
<sl-breadcrumb-item href="https://example.com/home/services/digital">
Digital Media
</sl-breadcrumb-item>
<sl-breadcrumb-item href="https://example.com/home/services/digital/web-design">
Web Design
</sl-breadcrumb-item>
</sl-breadcrumb>
```
### Custom Separators
Use the `separator` slot to change the separator that goes between breadcrumb items. Icons work well, but you can also use text or an image.
```html preview
<sl-breadcrumb>
<sl-icon name="dot" slot="separator"></sl-icon>
<sl-breadcrumb-item>First</sl-breadcrumb-item>
<sl-breadcrumb-item>Second</sl-breadcrumb-item>
<sl-breadcrumb-item>Third</sl-breadcrumb-item>
</sl-breadcrumb>
<br>
<sl-breadcrumb>
<sl-icon name="arrow-right" slot="separator"></sl-icon>
<sl-breadcrumb-item>First</sl-breadcrumb-item>
<sl-breadcrumb-item>Second</sl-breadcrumb-item>
<sl-breadcrumb-item>Third</sl-breadcrumb-item>
</sl-breadcrumb>
<br>
<sl-breadcrumb>
<span slot="separator">/</span>
<sl-breadcrumb-item>First</sl-breadcrumb-item>
<sl-breadcrumb-item>Second</sl-breadcrumb-item>
<sl-breadcrumb-item>Third</sl-breadcrumb-item>
</sl-breadcrumb>
```
### Prefixes
Use the `prefix` slot to add content before any breadcrumb item.
```html preview
<sl-breadcrumb>
<sl-breadcrumb-item>
<sl-icon slot="prefix" name="house"></sl-icon>
Home
</sl-breadcrumb-item>
<sl-breadcrumb-item>Articles</sl-breadcrumb-item>
<sl-breadcrumb-item>Traveling</sl-breadcrumb-item>
</sl-breadcrumb>
```
### Suffixes
Use the `suffix` slot to add content after any breadcrumb item.
```html preview
<sl-breadcrumb>
<sl-breadcrumb-item>Documents</sl-breadcrumb-item>
<sl-breadcrumb-item>Policies</sl-breadcrumb-item>
<sl-breadcrumb-item>
Security
<sl-icon slot="suffix" name="shield-lock"></sl-icon>
</sl-breadcrumb-item>
</sl-breadcrumb>
```
### With Dropdowns
Dropdown menus can be placed in a prefix or suffix slot to provide additional options.
```html preview
<sl-breadcrumb>
<sl-breadcrumb-item>Homepage</sl-breadcrumb-item>
<sl-breadcrumb-item>Our Services</sl-breadcrumb-item>
<sl-breadcrumb-item>Digital Media</sl-breadcrumb-item>
<sl-breadcrumb-item>
Web Design
<sl-dropdown slot="suffix">
<sl-button slot="trigger" size="small" circle>
<sl-icon label="More options" name="three-dots"></sl-icon>
</sl-button>
<sl-menu>
<sl-menu-item checked>Web Design</sl-menu-item>
<sl-menu-item>Web Development</sl-menu-item>
<sl-menu-item>Marketing</sl-menu-item>
</sl-menu>
</sl-dropdown>
</sl-breadcrumb-item>
</sl-breadcrumb>
```
[component-metadata:sl-breadcrumb]

View File

@@ -0,0 +1,221 @@
# Button Group
[component-header:sl-button-group]
Button groups can be used to group related buttons into sections.
```html preview
<sl-button-group>
<sl-button>Left</sl-button>
<sl-button>Center</sl-button>
<sl-button>Right</sl-button>
</sl-button-group>
```
## Examples
### Button Sizes
All button sizes are supported, but avoid mixing sizes within the same button group.
```html preview
<sl-button-group>
<sl-button size="small">Left</sl-button>
<sl-button size="small">Center</sl-button>
<sl-button size="small">Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button size="medium">Left</sl-button>
<sl-button size="medium">Center</sl-button>
<sl-button size="medium">Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button size="large">Left</sl-button>
<sl-button size="large">Center</sl-button>
<sl-button size="large">Right</sl-button>
</sl-button-group>
```
### Theme Buttons
Theme buttons are supported through the button's `type` attribute.
```html preview
<sl-button-group>
<sl-button type="primary">Left</sl-button>
<sl-button type="primary">Center</sl-button>
<sl-button type="primary">Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button type="success">Left</sl-button>
<sl-button type="success">Center</sl-button>
<sl-button type="success">Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button type="neutral">Left</sl-button>
<sl-button type="neutral">Center</sl-button>
<sl-button type="neutral">Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button type="warning">Left</sl-button>
<sl-button type="warning">Center</sl-button>
<sl-button type="warning">Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button type="danger">Left</sl-button>
<sl-button type="danger">Center</sl-button>
<sl-button type="danger">Right</sl-button>
</sl-button-group>
```
### Pill Buttons
Pill buttons are supported through the button's `pill` attribute.
```html preview
<sl-button-group>
<sl-button size="small" pill>Left</sl-button>
<sl-button size="small" pill>Center</sl-button>
<sl-button size="small" pill>Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button size="medium" pill>Left</sl-button>
<sl-button size="medium" pill>Center</sl-button>
<sl-button size="medium" pill>Right</sl-button>
</sl-button-group>
<br><br>
<sl-button-group>
<sl-button size="large" pill>Left</sl-button>
<sl-button size="large" pill>Center</sl-button>
<sl-button size="large" pill>Right</sl-button>
</sl-button-group>
```
### Dropdowns in Button Groups
Dropdowns can be placed inside button groups as long as the trigger is an `<sl-button>` element.
```html preview
<sl-button-group>
<sl-button>Button</sl-button>
<sl-button>Button</sl-button>
<sl-dropdown>
<sl-button slot="trigger" caret>Dropdown</sl-button>
<sl-menu>
<sl-menu-item>Item 1</sl-menu-item>
<sl-menu-item>Item 2</sl-menu-item>
<sl-menu-item>Item 3</sl-menu-item>
</sl-menu>
</sl-dropdown>
</sl-button-group>
```
### Split Buttons
Create a split button using a button and a dropdown.
```html preview
<sl-button-group>
<sl-button type="primary">Save</sl-button>
<sl-dropdown placement="bottom-end">
<sl-button slot="trigger" type="primary" caret></sl-button>
<sl-menu>
<sl-menu-item>Save</sl-menu-item>
<sl-menu-item>Save as&hellip;</sl-menu-item>
<sl-menu-item>Save all</sl-menu-item>
</sl-menu>
</sl-dropdown>
</sl-button-group>
```
### Tooltips in Button Groups
Buttons can be wrapped in tooltips to provide more detail when the user interacts with them.
```html preview
<sl-button-group>
<sl-tooltip content="I'm on the left">
<sl-button>Left</sl-button>
</sl-tooltip>
<sl-tooltip content="I'm in the middle">
<sl-button>Center</sl-button>
</sl-tooltip>
<sl-tooltip content="I'm on the right">
<sl-button>Right</sl-button>
</sl-tooltip>
</sl-button-group>
```
### Toolbar Example
Create interactive toolbars with button groups.
```html preview
<div class="button-group-toolbar">
<sl-button-group label="History">
<sl-tooltip content="Undo">
<sl-button><sl-icon name="arrow-counterclockwise"></sl-icon></sl-button>
</sl-tooltip>
<sl-tooltip content="Redo">
<sl-button><sl-icon name="arrow-clockwise"></sl-icon></sl-button>
</sl-tooltip>
</sl-button-group>
<sl-button-group label="Formatting">
<sl-tooltip content="Bold">
<sl-button><sl-icon name="type-bold"></sl-icon></sl-button>
</sl-tooltip>
<sl-tooltip content="Italic">
<sl-button><sl-icon name="type-italic"></sl-icon></sl-button>
</sl-tooltip>
<sl-tooltip content="Underline">
<sl-button><sl-icon name="type-underline"></sl-icon></sl-button>
</sl-tooltip>
</sl-button-group>
<sl-button-group label="Alignment">
<sl-tooltip content="Align Left">
<sl-button><sl-icon name="justify-left"></sl-icon></sl-button>
</sl-tooltip>
<sl-tooltip content="Align Center">
<sl-button><sl-icon name="justify"></sl-icon></sl-button>
</sl-tooltip>
<sl-tooltip content="Align Right">
<sl-button><sl-icon name="justify-right"></sl-icon></sl-button>
</sl-tooltip>
</sl-button-group>
</div>
<style>
.button-group-toolbar sl-button-group:not(:last-of-type) {
margin-right: var(--sl-spacing-x-small);
}
</style>
```
[component-metadata:sl-button-group]

View File

@@ -18,14 +18,14 @@ Use the `type` attribute to set the button's type.
<sl-button type="default">Default</sl-button>
<sl-button type="primary">Primary</sl-button>
<sl-button type="success">Success</sl-button>
<sl-button type="info">Info</sl-button>
<sl-button type="neutral">Neutral</sl-button>
<sl-button type="warning">Warning</sl-button>
<sl-button type="danger">Danger</sl-button>
```
### Sizes
Use the `size` prop to change a button's size.
Use the `size` attribute to change a button's size.
```html preview
<sl-button size="small">Small</sl-button>
@@ -33,9 +33,22 @@ Use the `size` prop to change a button's size.
<sl-button size="large">Large</sl-button>
```
### Outline Buttons
Use the `outline` attribute to draw outlined buttons with transparent backgrounds.
```html preview
<sl-button type="default" outline>Default</sl-button>
<sl-button type="primary" outline>Primary</sl-button>
<sl-button type="success" outline>Success</sl-button>
<sl-button type="neutral" outline>Neutral</sl-button>
<sl-button type="warning" outline>Warning</sl-button>
<sl-button type="danger" outline>Danger</sl-button>
```
### Pill Buttons
Use the `pill` prop to give buttons rounded edges.
Use the `pill` attribute to give buttons rounded edges.
```html preview
<sl-button size="small" pill>Small</sl-button>
@@ -45,7 +58,7 @@ Use the `pill` prop to give buttons rounded edges.
### Circle Buttons
Use the `circle` prop to create circular icon buttons.
Use the `circle` attribute to create circular icon buttons.
```html preview
<sl-button type="default" size="small" circle><sl-icon name="gear"></sl-icon></sl-button>
@@ -63,6 +76,19 @@ Use the `text` type to create text buttons that share the same size as regular b
<sl-button type="text" size="large">Text</sl-button>
```
### Link Buttons
It's often helpful to have a button that works like a link. This is possible by setting the `href` attribute, which will make the component render an `<a>` under the hood. This gives you all the default link behavior the browser provides (e.g. <kbd>CMD/CTRL/SHIFT + CLICK</kbd>) and exposes the `target` and `download` attributes.
```html preview
<sl-button href="https://example.com/">Link</sl-button>
<sl-button href="https://example.com/" target="_blank">New Window</sl-button>
<sl-button href="/assets/images/wordmark.svg" download="shoelace.svg">Download</sl-button>
<sl-button href="https://example.com/" disabled>Disabled</sl-button>
```
?> When a `target` is set, the link will receive `rel="noreferrer noopener"` for [security reasons](https://mathiasbynens.github.io/rel-noopener/).
### Setting a Custom Width
As expected, buttons can be given a custom width by setting its `width`. This is useful for making buttons span the full width of their container on smaller screens.
@@ -78,6 +104,24 @@ As expected, buttons can be given a custom width by setting its `width`. This is
Use the `prefix` and `suffix` slots to add icons.
```html preview
<sl-button type="default" size="small">
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
</sl-button>
<sl-button type="default" size="small">
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh
</sl-button>
<sl-button type="default" size="small">
<sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open
</sl-button>
<br><br>
<sl-button type="default">
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
@@ -93,11 +137,29 @@ Use the `prefix` and `suffix` slots to add icons.
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open
</sl-button>
<br><br>
<sl-button type="default" size="large">
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
</sl-button>
<sl-button type="default" size="large">
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh
</sl-button>
<sl-button type="default" size="large">
<sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open
</sl-button>
```
### Caret
Use the `caret` prop to add a dropdown indicator when a button will trigger a dropdown, menu, or popover.
Use the `caret` attribute to add a dropdown indicator when a button will trigger a dropdown, menu, or popover.
```html preview
<sl-button size="small" caret>Small</sl-button>
@@ -107,28 +169,72 @@ Use the `caret` prop to add a dropdown indicator when a button will trigger a dr
### Loading
Use the `loading` prop to make a button busy. The width will remain the same as before, preventing adjacent elements from moving around. Clicks will be suppressed until the loading state is removed.
Use the `loading` attribute to make a button busy. The width will remain the same as before, preventing adjacent elements from moving around. Clicks will be suppressed until the loading state is removed.
```html preview
<sl-button type="default" loading>Default</sl-button>
<sl-button type="primary" loading>Primary</sl-button>
<sl-button type="success" loading>Success</sl-button>
<sl-button type="info" loading>Info</sl-button>
<sl-button type="neutral" loading>Neutral</sl-button>
<sl-button type="warning" loading>Warning</sl-button>
<sl-button type="danger" loading>Danger</sl-button>
```
### Disabled
Use the `disabled` prop to disable a button. Clicks will be suppressed until the disabled state is removed.
Use the `disabled` attribute to disable a button. Clicks will be suppressed until the disabled state is removed.
```html preview
<sl-button type="default" disabled>Default</sl-button>
<sl-button type="primary" disabled>Primary</sl-button>
<sl-button type="success" disabled>Success</sl-button>
<sl-button type="info" disabled>Info</sl-button>
<sl-button type="neutral" disabled>Neutral</sl-button>
<sl-button type="warning" disabled>Warning</sl-button>
<sl-button type="danger" disabled>Danger</sl-button>
```
### Styling Buttons
This example demonstrates how to style buttons using a custom class. This is the recommended approach if you need to add additional variations. To customize an existing variation, modify the selector to target the button's type attribute instead of a class (e.g. `sl-button[type="primary"]`).
```html preview
<sl-button class="pink">Pink Button</sl-button>
<style>
sl-button.pink::part(base) {
/* Set design tokens for height and border width */
--sl-input-height-medium: 48px;
--sl-input-border-width: 4px;
border-radius: 0;
background-color: #ff1493;
border-top-color: #ff7ac1;
border-left-color: #ff7ac1;
border-bottom-color: #ad005c;
border-right-color: #ad005c;
color: white;
font-size: 1.125rem;
box-shadow: 0 2px 10px #0002;
transition: var(--sl-transition-medium) transform ease, var(--sl-transition-medium) border ease;
}
sl-button.pink::part(base):hover {
transform: scale(1.05) rotate(-1deg);
}
sl-button.pink::part(base):active {
border-top-color: #ad005c;
border-right-color: #ff7ac1;
border-bottom-color: #ff7ac1;
border-left-color: #ad005c;
transform: scale(1.05) rotate(-1deg) translateY(2px);
}
sl-button.pink::part(base):focus-visible {
outline: dashed 2px deeppink;
outline-offset: 4px;
}
</style>
```
[component-metadata:sl-button]

144
docs/components/card.md Normal file
View File

@@ -0,0 +1,144 @@
# Card
[component-header:sl-card]
Cards can be used to group related subjects in a container.
```html preview
<sl-card class="card-overview">
<img
slot="image"
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
alt="A kitten sits patiently between a terracotta pot and decorative grasses."
>
<strong>Mittens</strong><br>
This kitten is as cute as he is playful. Bring him home today!<br>
<small>6 weeks old</small>
<div slot="footer">
<sl-button type="primary" pill>More Info</sl-button>
<sl-rating></sl-rating>
</div>
</sl-card>
<style>
.card-overview {
max-width: 300px;
}
.card-overview small {
color: rgb(var(--sl-color-neutral-500));
}
.card-overview [slot="footer"] {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
```
## Examples
## Basic Card
Basic cards aren't very exciting, but they can display any content you want them to.
```html preview
<sl-card class="card-basic">
This is just a basic card. No image, no header, and no footer. Just your content.
</sl-card>
<style>
.card-basic {
max-width: 300px;
}
</style>
```
## Card with Header
Headers can be used to display titles and more.
```html preview
<sl-card class="card-header">
<div slot="header">
Header Title
<sl-icon-button name="gear"></sl-icon-button>
</div>
This card has a header. You can put all sorts of things in it!
</sl-card>
<style>
.card-header {
max-width: 300px;
}
.card-header [slot="header"] {
display: flex;
align-items: center;
justify-content: space-between;
}
.card-header h3 {
margin: 0;
}
.card-header sl-icon-button {
font-size: var(--sl-font-size-medium);
}
</style>
```
## Card with Footer
Footers can be used to display actions, summaries, or other relevant content.
```html preview
<sl-card class="card-footer">
This card has a footer. You can put all sorts of things in it!
<div slot="footer">
<sl-rating></sl-rating>
<sl-button slot="footer" type="primary">Preview</sl-button>
</div>
</sl-card>
<style>
.card-footer {
max-width: 300px;
}
.card-footer [slot="footer"] {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
```
## Images
Cards accept an `image` slot. The image is displayed atop the card and stretches to fit.
```html preview
<sl-card class="card-image">
<img
slot="image"
src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80"
alt="A kitten walks towards camera on top of pallet."
>
This is a kitten, but not just any kitten. This kitten likes walking along pallets.
</sl-card>
<style>
.card-image {
max-width: 300px;
}
</style>
```
[component-metadata:sl-card]

View File

@@ -8,7 +8,7 @@ Checkboxes allow the user to toggle an option on or off.
<sl-checkbox>Checkbox</sl-checkbox>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
## Examples

View File

@@ -15,12 +15,14 @@ Color pickers allow the user to select a color.
Use the `opacity` attribute to enable the opacity slider. When this is enabled, the value will be displayed as HEXA, RGBA, or HSLA based on `format`.
```html preview
<sl-color-picker opacity format="hsl"></sl-color-picker>
<sl-color-picker opacity></sl-color-picker>
```
### Formats
Set the color picker's format with the `format` attribute. Valid options include `hex`, `rgb`, and `hsl`. Note that the color picker will accept any parsable format (including CSS color names) regardless of this option.
Set the color picker's format with the `format` attribute. Valid options include `hex`, `rgb`, and `hsl`. Note that the color picker's input will accept any parsable format (including CSS color names) regardless of this option.
To prevent users from toggling the format themselves, add the `no-format-toggle` attribute.
```html preview
<sl-color-picker format="hex" value="#4a90e2"></sl-color-picker>
@@ -28,6 +30,17 @@ Set the color picker's format with the `format` attribute. Valid options include
<sl-color-picker format="hsl" value="hsl(290, 87%, 47%)"></sl-color-picker>
```
### Sizes
Use the `size` attribute to change the color picker's trigger size.
```html preview
<sl-color-picker size="small"></sl-color-picker>
<sl-color-picker size="medium"></sl-color-picker>
<sl-color-picker size="large"></sl-color-picker>
```
### Inline
The color picker can be rendered inline instead of in a dropdown using the `inline` attribute.

View File

@@ -0,0 +1,140 @@
# Context Menu
[component-header:sl-context-menu]
Context menus offer additional options through a menu that opens at the pointer's location, usually activated by a right-click.
Context menus are designed to work with [menus](/components/menu) and [menu items](/components/menu-item). The menu must include `slot="menu"`. Other content you provide will be part of the context menu's target area.
```html preview
<sl-context-menu>
<div style="height: 200px; background: rgb(var(--sl-color-neutral-100)); display: flex; align-items: center; justify-content: center; padding: 1rem;">
Right-click to activate the context menu
</div>
<sl-menu slot="menu">
<sl-menu-item value="undo">Undo</sl-menu-item>
<sl-menu-item value="redo">Redo</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
<sl-menu-item value="delete">Delete</sl-menu-item>
</sl-menu>
</sl-context-menu>
```
## Examples
### Handling Selections
The [menu component](/components/menu) emits an `sl-select` event when a menu item is selected. You can use this to handle selections. The selected item will be available in `event.detail.item`.
```html preview
<div class="context-menu-selections">
<sl-context-menu>
<div style="height: 200px; background: rgb(var(--sl-color-neutral-100)); display: flex; align-items: center; justify-content: center; padding: 1rem;">
Right-click to activate the context menu
</div>
<sl-menu slot="menu">
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
</sl-menu>
</sl-context-menu>
</div>
<script>
const container = document.querySelector('.context-menu-selections');
const menu = container.querySelector('sl-menu');
const result = container.querySelector('.result');
menu.addEventListener('sl-select', event => {
console.log(`You selected: ${event.detail.item.value}`);
});
</script>
```
### Inline
The context menu uses `display: contents`, so it will assume the shape of the content you slot in.
```html preview
<sl-context-menu>
<span style="background: rgb(var(--sl-color-neutral-100)); padding: .5rem 1rem;">
Right-click here
</span>
<sl-menu slot="menu">
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
</sl-menu>
</sl-context-menu>
```
### Placement
The preferred placement of the context menu can be set with the `placement` attribute. Note that the actual position may vary to ensure the menu remains in the viewport.
```html preview
<sl-context-menu placement="top-end">
<div style="height: 200px; background: rgb(var(--sl-color-neutral-100)); display: flex; align-items: center; justify-content: center; padding: 1rem;">
Right-click to activate the context menu
</div>
<sl-menu slot="menu">
<sl-menu-item value="undo">Undo</sl-menu-item>
<sl-menu-item value="redo">Redo</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
<sl-menu-item value="delete">Delete</sl-menu-item>
</sl-menu>
</sl-context-menu>
```
### Detecting the Target Item
A single context menu can wrap a number of items. To detect the item that activated the context menu...
TODO
```html preview
<div class="context-menu-detecting">
<sl-context-menu>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
<sl-menu slot="menu">
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
</sl-menu>
</sl-context-menu>
</div>
<style>
.context-menu-detecting ul {
max-width: 300px;
list-style: none;
padding: 0;
margin: 0;
}
.context-menu-detecting li {
background: rgb(var(--sl-color-neutral-100));
padding: .5rem 1rem;
margin: 0 0 2px 0;
}
</style>
```
[component-metadata:sl-context-menu]

View File

@@ -26,7 +26,7 @@ Use the `disable` attribute to prevent the details from expanding.
### Grouping Details
Details are designed to function independently, but you can simulate a group or "accordion" where only one is shown at a time by listening for the `slShow` event.
Details are designed to function independently, but you can simulate a group or "accordion" where only one is shown at a time by listening for the `sl-show` event.
```html preview
<div class="details-group-example">
@@ -50,14 +50,14 @@ Details are designed to function independently, but you can simulate a group or
const container = document.querySelector('.details-group-example');
// Close all other details when one is shown
container.addEventListener('slShow', event => {
container.addEventListener('sl-show', event => {
[...container.querySelectorAll('sl-details')].map(details => (details.open = event.target === details));
});
</script>
<style>
.details-group-example sl-details:not(:last-of-type) {
margin-bottom: var(--sl-spacing-xx-small);
margin-bottom: var(--sl-spacing-2x-small);
}
</style>
```

View File

@@ -2,7 +2,7 @@
[component-header:sl-dialog]
Dialogs appear above the page and require the user's immediate attention.
Dialogs, sometimes called "modals", appear above the page and require the user's immediate attention.
```html preview
<sl-dialog label="Dialog" class="dialog-overview">
@@ -13,14 +13,12 @@ Dialogs appear above the page and require the user's immediate attention.
<sl-button>Open Dialog</sl-button>
<script>
(() => {
const dialog = document.querySelector('.dialog-overview');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
const dialog = document.querySelector('.dialog-overview');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
})();
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
</script>
```
@@ -45,14 +43,12 @@ Use the `--width` custom property to set the dialog's width.
<sl-button>Open Dialog</sl-button>
<script>
(() => {
const dialog = document.querySelector('.dialog-width');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
const dialog = document.querySelector('.dialog-width');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
})();
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
</script>
```
@@ -62,7 +58,7 @@ By design, a dialog's height will never exceed that of the viewport. As such, di
```html preview
<sl-dialog label="Dialog" class="dialog-scrolling">
<div style="height: 150vh; border: dashed 2px var(--sl-color-gray-80); padding: 0 1rem;">
<div style="height: 150vh; border: dashed 2px rgb(var(--sl-color-neutral-200)); padding: 0 1rem;">
<p>Scroll down and give it a try! 👇</p>
</div>
<sl-button slot="footer" type="primary">Close</sl-button>
@@ -71,40 +67,66 @@ By design, a dialog's height will never exceed that of the viewport. As such, di
<sl-button>Open Dialog</sl-button>
<script>
(() => {
const dialog = document.querySelector('.dialog-scrolling');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
const dialog = document.querySelector('.dialog-scrolling');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
})();
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
</script>
```
### Ignoring Clicks on the Overlay
### Preventing the Dialog from Closing
By default, dialogs are closed when the user clicks or taps on the overlay. To prevent this behavior, cancel the `slOverlayDismiss` event.
By default, dialogs will close when the user clicks the close button, clicks the overlay, or presses the <kbd>Escape</kbd> key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
To keep the dialog open in such cases, you can cancel the `sl-request-close` event. When canceled, the dialog will remain open and pulse briefly to draw the user's attention to it.
```html preview
<sl-dialog label="Dialog" class="dialog-no-overlay-dismiss">
This dialog will not be closed when you click outside of it.
<sl-dialog label="Dialog" class="dialog-deny-close">
This dialog will not close unless you use the button below.
<sl-button slot="footer" type="primary">Save &amp; Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
<script>
const dialog = document.querySelector('.dialog-deny-close');
const openButton = dialog.nextElementSibling;
const saveButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show());
saveButton.addEventListener('click', () => dialog.hide());
dialog.addEventListener('sl-request-close', event => event.preventDefault());
</script>
```
### Customizing Initial Focus
By default, the dialog's panel will gain focus when opened. This allows the first tab press to focus on the first tabbable element within the dialog. To set focus on a different element, listen for and cancel the `sl-initial-focus` event.
```html preview
<sl-dialog label="Dialog" class="dialog-focus">
<sl-input placeholder="I will have focus when the dialog is opened"></sl-input>
<sl-button slot="footer" type="primary">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
<script>
(() => {
const dialog = document.querySelector('.dialog-no-overlay-dismiss');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
const dialog = document.querySelector('.dialog-focus');
const input = dialog.querySelector('sl-input');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
dialog.addEventListener('slOverlayDismiss', event => event.preventDefault());
})();
dialog.addEventListener('sl-initial-focus', event => {
event.preventDefault();
input.focus({ preventScroll: true });
});
</script>
```

View File

@@ -0,0 +1,71 @@
# Divider
[component-header:sl-divider]
Dividers are used to visually separate or group elements.
```html preview
<sl-divider></sl-divider>
```
## Examples
### Width
Use the `--width` custom property to change the width of the divider.
```html preview
<sl-divider style="--width: 4px;"></sl-divider>
```
### Color
Use the `--color` custom property to change the color of the divider.
```html preview
<sl-divider style="--color: tomato;"></sl-divider>
```
### Spacing
Use the `--spacing` custom property to change the amount of space between the divider and it's neighboring elements.
```html preview
<div style="text-align: center;">
Above
<sl-divider style="--spacing: 2rem;"></sl-divider>
Below
</div>
```
### Vertical
Add the `vertical` attribute to draw the divider in a vertical orientation. The divider will span the full height of its container. Vertical dividers work especially well inside of a flex container.
```html preview
<div style="display: flex; align-items: center; height: 2rem;">
First
<sl-divider vertical></sl-divider>
Middle
<sl-divider vertical></sl-divider>
Last
</div>
```
### Menu Dividers
Use dividers in [menus](/components/menu) to visually group menu items.
```html preview
<sl-menu style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item value="1">Option 1</sl-menu-item>
<sl-menu-item value="2">Option 2</sl-menu-item>
<sl-menu-item value="3">Option 3</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item value="4">Option 4</sl-menu-item>
<sl-menu-item value="5">Option 5</sl-menu-item>
<sl-menu-item value="6">Option 6</sl-menu-item>
</sl-menu>
```
[component-metadata:sl-divider]

View File

@@ -13,40 +13,36 @@ Drawers slide in from a container to expose additional options and information.
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-overview');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-overview');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
## Examples
### Slide in From Left
### Slide in From Start
To make the drawer slide in from the left, set the `placement` attribute to `left`.
By default, drawers slide in from the end. To make the drawer slide in from the start, set the `placement` attribute to `start`.
```html preview
<sl-drawer label="Drawer" placement="left" class="drawer-placement-left">
This drawer slides in from the left.
<sl-drawer label="Drawer" placement="start" class="drawer-placement-start">
This drawer slides in from the start.
<sl-button slot="footer" type="primary">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-placement-left');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-placement-start');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
@@ -63,14 +59,12 @@ To make the drawer slide in from the top, set the `placement` attribute to `top`
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-placement-top');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-placement-top');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
@@ -87,24 +81,22 @@ To make the drawer slide in from the bottom, set the `placement` attribute to `b
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-placement-bottom');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-placement-bottom');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
### Contained to an Element
By default, the drawer slides out of its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport. To make the drawer slide out of its parent element, set this prop and add `position: relative` to the parent.
By default, the drawer slides out of its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport. To make the drawer slide out of its parent element, add the `contained` attribute and `position: relative` to the parent.
```html preview
<div
style="position: relative; border: solid 2px var(--sl-color-gray-80); height: 300px; padding: 1rem; margin-bottom: 1rem;"
style="position: relative; border: solid 2px rgb(var(--sl-panel-border-color)); height: 300px; padding: 1rem; margin-bottom: 1rem;"
>
The drawer will be contained to this box. This content won't shift or be affected in any way when the drawer opens.
@@ -117,14 +109,12 @@ By default, the drawer slides out of its [containing block](https://developer.mo
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-contained');
const openButton = drawer.parentElement.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-contained');
const openButton = drawer.parentElement.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
@@ -141,14 +131,12 @@ Use the `--size` custom property to set the drawer's size. This will be applied
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-custom-size');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-custom-size');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
@@ -158,7 +146,7 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
```html preview
<sl-drawer label="Drawer" class="drawer-scrolling">
<div style="height: 150vh; border: dashed 2px var(--sl-color-gray-80); padding: 0 1rem;">
<div style="height: 150vh; border: dashed 2px rgb(var(--sl-color-neutral-200)); padding: 0 1rem;">
<p>Scroll down and give it a try! 👇</p>
</div>
<sl-button slot="footer" type="primary">Close</sl-button>
@@ -167,40 +155,67 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-scrolling');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-scrolling');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
})();
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
</script>
```
### Ignoring Clicks on the Overlay
### Preventing the Drawer from Closing
By default, drawers will close when the user clicks the close button, clicks the overlay, or presses the <kbd>Escape</kbd> key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
To keep the drawer open in such cases, you can cancel the `sl-request-close` event. When canceled, the drawer will remain open and pulse briefly to draw the user's attention to it.
By default, drawers are closed when the user clicks or taps on the overlay. To prevent this behavior, cancel the `slOverlayDismiss` event.
```html preview
<sl-drawer label="Drawer" class="drawer-no-overlay-dismiss">
This drawer will not be closed when you click outside of it.
<sl-drawer label="Drawer" class="drawer-deny-close">
This dialog will not close unless you use the button below.
<sl-button slot="footer" type="primary">Save &amp; Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
<script>
const drawer = document.querySelector('.drawer-deny-close');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
drawer.addEventListener('sl-request-close', event => event.preventDefault());
</script>
```
### Customizing Initial Focus
By default, the drawer's panel will gain focus when opened. This allows the first tab press to focus on the first tabbable element within the drawer. To set focus on a different element, listen for and cancel the `sl-initial-focus` event.
```html preview
<sl-drawer label="Drawer" class="drawer-focus">
<sl-input placeholder="I will have focus when the drawer is opened"></sl-input>
<sl-button slot="footer" type="primary">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
<script>
(() => {
const drawer = document.querySelector('.drawer-no-overlay-dismiss');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
const drawer = document.querySelector('.drawer-focus');
const input = drawer.querySelector('sl-input');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
drawer.addEventListener('slOverlayDismiss', event => event.preventDefault());
})();
drawer.addEventListener('sl-initial-focus', event => {
event.preventDefault();
input.focus({ preventScroll: true });
});
</script>
```

View File

@@ -6,7 +6,7 @@ Dropdowns expose additional content that "drops down" in a panel.
Dropdowns consist of a trigger and a panel. By default, activating the trigger will expose the panel and interacting outside of the panel will close it.
Dropdowns are designed to work well with [menus](/components/menu.md) to provide a list of options the user can select from. However, dropdowns can also be used in lower-level applications (e.g. [color picker](/components/color-picker.md) and [select](/components/select.md)). The API gives you complete control over showing, hiding, and positioning the panel.
Dropdowns are designed to work well with [menus](/components/menu) to provide a list of options the user can select from. However, dropdowns can also be used in lower-level applications (e.g. [color picker](/components/color-picker) and [select](/components/select)). The API gives you complete control over showing, hiding, and positioning the panel.
```html preview
<sl-dropdown>
@@ -15,10 +15,10 @@ Dropdowns are designed to work well with [menus](/components/menu.md) to provide
<sl-menu-item>Dropdown Item 1</sl-menu-item>
<sl-menu-item>Dropdown Item 2</sl-menu-item>
<sl-menu-item>Dropdown Item 3</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item checked>Checked</sl-menu-item>
<sl-menu-item disabled>Disabled</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item>
Prefix
<sl-icon slot="prefix" name="gift"></sl-icon>
@@ -33,6 +33,33 @@ Dropdowns are designed to work well with [menus](/components/menu.md) to provide
## Examples
### Getting the Selected Item
When dropdowns are used with [menus](/components/menu), you can listen for the `sl-select` event to determine which menu item was selected. The menu item element will be exposed in `event.detail.item`. You can set `value` props to make it easier to identify commands.
```html preview
<div class="dropdown-selection">
<sl-dropdown>
<sl-button slot="trigger" caret>Edit</sl-button>
<sl-menu>
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
</sl-menu>
</sl-dropdown>
</div>
<script>
const container = document.querySelector('.dropdown-selection');
const dropdown = container.querySelector('sl-dropdown');
dropdown.addEventListener('sl-select', event => {
const selectedItem = event.detail.item;
console.log(selectedItem.value);
});
</script>
```
### Placement
The preferred placement of the dropdown can be set with the `placement` attribute. Note that the actual position may vary to ensure the panel remains in the viewport.
@@ -44,7 +71,7 @@ The preferred placement of the dropdown can be set with the `placement` attribut
<sl-menu-item>Cut</sl-menu-item>
<sl-menu-item>Copy</sl-menu-item>
<sl-menu-item>Paste</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item>Find</sl-menu-item>
<sl-menu-item>Replace</sl-menu-item>
</sl-menu>
@@ -62,7 +89,7 @@ The distance from the panel to the trigger can be customized using the `distance
<sl-menu-item>Cut</sl-menu-item>
<sl-menu-item>Copy</sl-menu-item>
<sl-menu-item>Paste</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item>Find</sl-menu-item>
<sl-menu-item>Replace</sl-menu-item>
</sl-menu>
@@ -80,11 +107,45 @@ The offset of the panel along the trigger can be customized using the `skidding`
<sl-menu-item>Cut</sl-menu-item>
<sl-menu-item>Copy</sl-menu-item>
<sl-menu-item>Paste</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item>Find</sl-menu-item>
<sl-menu-item>Replace</sl-menu-item>
</sl-menu>
</sl-dropdown>
```
### Hoisting
Dropdown panels will be clipped if they're inside a container that has `overflow: auto|hidden`. The `hoist` attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its containing block, which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
```html preview
<div class="dropdown-hoist">
<sl-dropdown>
<sl-button slot="trigger" caret>No Hoist</sl-button>
<sl-menu>
<sl-menu-item>Item 1</sl-menu-item>
<sl-menu-item>Item 2</sl-menu-item>
<sl-menu-item>Item 3</sl-menu-item>
</sl-menu>
</sl-dropdown>
<sl-dropdown hoist>
<sl-button slot="trigger" caret>Hoist</sl-button>
<sl-menu>
<sl-menu-item>Item 1</sl-menu-item>
<sl-menu-item>Item 2</sl-menu-item>
<sl-menu-item>Item 3</sl-menu-item>
</sl-menu>
</sl-dropdown>
</div>
<style>
.dropdown-hoist {
border: solid 2px rgb(var(--sl-panel-border-color));
padding: var(--sl-spacing-medium);
overflow: hidden;
}
</style>
```
[component-metadata:sl-dropdown]

View File

@@ -4,9 +4,11 @@
Forms collect data that can easily be processed and sent to a server.
All of Shoelace's components make use of the [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) to encapsulate markup, style, and behavior. One caveat of this approach is that native `<form>` elements don't recognize Shoelace form controls.
All Shoelace components make use of a [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) to encapsulate markup, styles, and behavior. One caveat of this approach is that native `<form>` elements will not recognize Shoelace form controls.
This component solves that problem by serializing _both_ Shoelace form controls and native form controls. The resulting form data is exposed in the `slSubmit` event in a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object.
This component solves that problem by serializing _both_ Shoelace form controls and native form controls when the form is submitted. The resulting form data is exposed in the `sl-submit` event as a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object in `event.detail.formData`. You can also find an array of form controls in `event.detail.formControls`.
Shoelace forms don't make use of `action` and `method` attributes and they don't submit the same way as native forms. To handle submission, you need to listen for the `sl-submit` event as shown in the example below and make an XHR request with the resulting form data.
```html preview
<sl-form class="form-overview">
@@ -28,7 +30,8 @@ This component solves that problem by serializing _both_ Shoelace form controls
<script>
const form = document.querySelector('.form-overview');
form.addEventListener('slSubmit', event => {
// Watch for the slSubmit event
form.addEventListener('sl-submit', event => {
const formData = event.detail.formData;
let output = '';
@@ -64,6 +67,149 @@ This component solves that problem by serializing _both_ Shoelace form controls
</script>
```
?> Shoelace forms don't make use of `action` and `method` attributes and they don't submit automatically like native forms. To handle submission, you need to listen for the `slSubmit` event as shown in the example above.
## Form Control Validation
Client-side validation can be enabled through the browser's [Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation) for many form controls. You can enable it using props such as `required`, `pattern`, `minlength`, and `maxlength`. As the user interacts with the form control, the `invalid` attribute will reflect its validity based on its current value and the constraints that have been defined.
When a form control is invalid, the containing form will not be submitted. Instead, the browser will show the user a relevant error message. If you don't want to use client-side validation, you can suppress this behavior by adding `novalidate` to the `<sl-form>` element.
All form controls support validation, but not all validation props are available for every component. Refer to a component's documentation to see which validation props it supports.
!> Client-side validation can be used to improve the UX of forms, but it is not a replacement for server-side validation. **You should always validate and sanitize user input on the server!**
### Required Fields
To make a field required, use the `required` prop. The form will not be submitted if a required form control is empty.
```html preview
<sl-form class="input-validation-required">
<sl-input name="name" label="Name" required></sl-input>
<br>
<sl-select label="Favorite Animal" clearable required>
<sl-menu-item value="birds">Birds</sl-menu-item>
<sl-menu-item value="cats">Cats</sl-menu-item>
<sl-menu-item value="dogs">Dogs</sl-menu-item>
<sl-menu-item value="other">Other</sl-menu-item>
</sl-select>
<br>
<sl-textarea name="comment" label="Comment" required></sl-textarea>
<br>
<sl-checkbox required>Check me before submitting</sl-checkbox>
<br><br>
<sl-button type="primary" submit>Submit</sl-button>
</sl-form>
<script>
const form = document.querySelector('.input-validation-required');
form.addEventListener('sl-submit', () => alert('All fields are valid!'));
</script>
```
### Input Patterns
To restrict a value to a specific [pattern](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern), use the `pattern` attribute. This example only allows the letters A-Z, so the form will not submit if a number or symbol is entered. This only works with `<sl-input>` elements.
```html preview
<sl-form class="input-validation-pattern">
<sl-input name="letters" required label="Letters" pattern="[A-Za-z]+"></sl-input>
<br>
<sl-button type="primary" submit>Submit</sl-button>
</sl-form>
<script>
const form = document.querySelector('.input-validation-pattern');
form.addEventListener('sl-submit', () => alert('All fields are valid!'));
</script>
```
### Input Types
Some input types will automatically trigger constraints, such as `email` and `url`.
```html preview
<sl-form class="input-validation-type">
<sl-input type="email" label="Email" placeholder="you@example.com" required></sl-input>
<br>
<sl-input type="url" label="URL" placeholder="https://example.com/" required></sl-input>
<br>
<sl-button type="primary" submit>Submit</sl-button>
</sl-form>
<script>
const form = document.querySelector('.input-validation-type');
form.addEventListener('sl-submit', () => alert('All fields are valid!'));
</script>
```
### Custom Validation
To create a custom validation error, use the `setCustomValidity` method. The form will not be submitted when this method is called with anything other than an empty string, and its message will be shown by the browser as the validation error. To make the input valid again, call the method a second time with an empty string as the argument.
```html preview
<sl-form class="input-validation-custom">
<sl-input label="Type 'shoelace'" required></sl-input>
<br>
<sl-button type="primary" submit>Submit</sl-button>
</sl-form>
<script>
const form = document.querySelector('.input-validation-custom');
const input = form.querySelector('sl-input');
form.addEventListener('sl-submit', () => alert('All fields are valid!'));
input.addEventListener('sl-input', () => {
if (input.value === 'shoelace') {
input.setCustomValidity('');
} else {
input.setCustomValidity('Hey, you\'re supposed to type \'shoelace\' before submitting this!');
}
});
</script>
```
### Custom Validation Styles
The `invalid` attribute reflects the form control's validity, so you can style invalid fields using the `[invalid]` selector. The example below demonstrates how you can give erroneous fields a different appearance. Type something other than "shoelace" to demonstrate this.
```html preview
<sl-input class="custom-input" required pattern="shoelace">
<small slot="help-text">Please enter "shoelace" to continue</small>
</sl-input>
<style>
.custom-input[invalid]:not([disabled])::part(label),
.custom-input[invalid]:not([disabled])::part(help-text) {
color: rgb(var(--sl-color-danger-600));
}
.custom-input[invalid]:not([disabled])::part(base) {
border-color: rgb(var(--sl-color-danger-500));
}
.custom-input[invalid]:focus-within::part(base) {
box-shadow: 0 0 0 var(--sl-focus-ring-width) rgb(var(--sl-color-danger-500) / var(--sl-focus-ring-alpha));
}
</style>
```
### Third-party Validation
To opt out of the browser's built-in validation and use your own, add the `novalidate` attribute to the form. This will ignore all constraints and prevent the browser from showing its own warnings when form controls are invalid.
Remember that the `invalid` attribute on form controls reflects validity as defined by the [Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation). You can set it initially, but the `invalid` attribute will update as the user interacts with the form control. As such, you should not rely on it to set invalid styles using a custom validation library.
Instead, toggle a class and target it in your stylesheet as shown below.
```html
<sl-form novalidate>
<sl-input class="invalid"></sl-input>
</sl-form>
<style>
sl-input.invalid {
...
}
</style>
```
[component-metadata:sl-form]

View File

@@ -0,0 +1,58 @@
# Format Bytes
[component-header:sl-format-bytes]
Formats a number as a human readable bytes value.
```html preview
<div class="format-bytes-overview">
The file is <sl-format-bytes value="1000"></sl-format-bytes> in size.
<br><br>
<sl-input type="number" value="1000" label="Number to Format" style="max-width: 180px;"></sl-input>
</div>
<script>
const container = document.querySelector('.format-bytes-overview');
const formatter = container.querySelector('sl-format-bytes');
const input = container.querySelector('sl-input');
input.addEventListener('sl-input', () => formatter.value = input.value || 0);
</script>
```
## Examples
### Formatting Bytes
Set the `value` attribute to a number to get the value in bytes.
```html preview
<sl-format-bytes value="12"></sl-format-bytes><br>
<sl-format-bytes value="1200"></sl-format-bytes><br>
<sl-format-bytes value="1200000"></sl-format-bytes><br>
<sl-format-bytes value="1200000000"></sl-format-bytes>
```
### Formatting Bits
To get the value in bits, set the `unit` attribute to `bits`.
```html preview
<sl-format-bytes value="12" unit="bits"></sl-format-bytes><br>
<sl-format-bytes value="1200" unit="bits"></sl-format-bytes><br>
<sl-format-bytes value="1200000" unit="bits"></sl-format-bytes><br>
<sl-format-bytes value="1200000000" unit="bits"></sl-format-bytes>
```
### Localization
Use the `locale` attribute to set the number formatting locale.
```html preview
<sl-format-bytes value="12" locale="de"></sl-format-bytes><br>
<sl-format-bytes value="1200" locale="de"></sl-format-bytes><br>
<sl-format-bytes value="1200000" locale="de"></sl-format-bytes><br>
<sl-format-bytes value="1200000000" locale="de"></sl-format-bytes>
```
[component-metadata:sl-format-bytes]

View File

@@ -0,0 +1,64 @@
# Format Date
[component-header:sl-format-date]
Formats a date/time using the specified locale and options.
Localization is handled by the browser's [`Intl.DateTimeFormat` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat). No language packs are required.
```html preview
<!-- Shoelace 2 release date 🎉 -->
<sl-format-date date="2020-07-15T09:17:00-04:00"></sl-format-date>
```
The `date` attribute determines the date/time to use when formatting. It must be a string that [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) can interpret or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object set via JavaScript. If omitted, the current date/time will be assumed.
?> When using strings, avoid ambiguous dates such as `03/04/2020` which can be interpreted as March 4 or April 3 depending on the user's browser and locale. Instead, always use a valid [ISO 8601 date time string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#Date_Time_String_Format) to ensure the date will be parsed properly by all clients.
## Examples
### Date & Time Formatting
Formatting options are based on those found in the [`Intl.DateTimeFormat` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat). When formatting options are provided, the date/time will be formatted according to those values. When no formatting options are provided, a localized, numeric date will be displayed instead.
```html preview
<!-- Human-readable date -->
<sl-format-date month="long" day="numeric" year="numeric"></sl-format-date><br>
<!-- Time -->
<sl-format-date hour="numeric" minute="numeric"></sl-format-date><br>
<!-- Weekday -->
<sl-format-date weekday="long"></sl-format-date><br>
<!-- Month -->
<sl-format-date month="long"></sl-format-date><br>
<!-- Year -->
<sl-format-date year="numeric"></sl-format-date><br>
<!-- No formatting options -->
<sl-format-date></sl-format-date>
```
### Hour Formatting
By default, the browser will determine whether to use 12-hour or 24-hour time. To force one or the other, set the `hour-format` attribute to `12` or `24`.
```html preview
<sl-format-date hour="numeric" minute="numeric" hour-format="12"></sl-format-date><br>
<sl-format-date hour="numeric" minute="numeric" hour-format="24"></sl-format-date>
```
### Localization
Use the `locale` attribute to set the date/time formatting locale.
```html preview
English: <sl-format-date locale="en"></sl-format-date><br>
French: <sl-format-date locale="fr"></sl-format-date><br>
Russian: <sl-format-date locale="ru"></sl-format-date><br>
```
[component-metadata:sl-format-date]

View File

@@ -0,0 +1,61 @@
# Format Number
[component-header:sl-format-number]
Formats a number using the specified locale and options.
Localization is handled by the browser's [`Intl.NumberFormat` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). No language packs are required.
```html preview
<div class="format-number-overview">
<sl-format-number value="1000"></sl-format-number>
<br><br>
<sl-input type="number" value="1000" label="Number to Format" style="max-width: 180px;"></sl-input>
</div>
<script>
const container = document.querySelector('.format-number-overview');
const formatter = container.querySelector('sl-format-number');
const input = container.querySelector('sl-input');
input.addEventListener('sl-input', () => formatter.value = input.value || 0);
</script>
```
## Examples
### Percentages
To get the value as a percent, set the `type` attribute to `percent`.
```html preview
<sl-format-number type="percent" value="0"></sl-format-number><br>
<sl-format-number type="percent" value=".25"></sl-format-number><br>
<sl-format-number type="percent" value=".50"></sl-format-number><br>
<sl-format-number type="percent" value=".75"></sl-format-number><br>
<sl-format-number type="percent" value="1"></sl-format-number>
```
### Localization
Use the `locale` attribute to set the number formatting locale.
```html preview
English: <sl-format-number value="2000" locale="en" minimum-fraction-digits="2"></sl-format-number><br>
German: <sl-format-number value="2000" locale="de" minimum-fraction-digits="2"></sl-format-number><br>
Russian: <sl-format-number value="2000" locale="ru" minimum-fraction-digits="2"></sl-format-number>
```
### Currency
To format a number as a monetary value, set the `type` attribute to `currency` and set the `currency` attribute to the desired ISO 4217 currency code. You should also specify `locale` to ensure the the number is formatted correctly for the target locale.
```html preview
<sl-format-number type="currency" currency="USD" value="2000" locale="en-US"></sl-format-number><br>
<sl-format-number type="currency" currency="GBP" value="2000" locale="en-GB"></sl-format-number><br>
<sl-format-number type="currency" currency="EUR" value="2000" locale="de"></sl-format-number><br>
<sl-format-number type="currency" currency="RUB" value="2000" locale="ru"></sl-format-number><br>
<sl-format-number type="currency" currency="CNY" value="2000" locale="zh-cn"></sl-format-number>
```
[component-metadata:sl-format-number]

View File

@@ -0,0 +1,78 @@
# Icon Button
[component-header:sl-icon-button]
Icons buttons are simple, icon-only buttons that can be used for actions and in toolbars.
For a full list of icons that come bundled with Shoelace, refer to the [icon component](/components/icon).
```html preview
<sl-icon-button name="gear" label="Settings"></sl-icon-button>
```
## Examples
### Sizes
Icon buttons inherit their parent element's `font-size`.
```html preview
<sl-icon-button name="pencil" label="Edit" style="font-size: 1.5rem;"></sl-icon-button>
<sl-icon-button name="pencil" label="Edit" style="font-size: 2rem;"></sl-icon-button>
<sl-icon-button name="pencil" label="Edit" style="font-size: 2.5rem;"></sl-icon-button>
```
### Colors
Icon buttons are designed to have a uniform appearance, so their color is not inherited. However, you can still customize them by styling the `base` part.
```html preview
<div class="icon-button-color">
<sl-icon-button name="type-bold" label="Bold"></sl-icon-button>
<sl-icon-button name="type-italic" label="Italic"></sl-icon-button>
<sl-icon-button name="type-underline" label="Underline"></sl-icon-button>
</div>
<style>
.icon-button-color sl-icon-button::part(base) {
color: #b00091;
}
.icon-button-color sl-icon-button::part(base):hover,
.icon-button-color sl-icon-button::part(base):focus {
color: #c913aa;
}
.icon-button-color sl-icon-button::part(base):active {
color: #960077;
}
</style>
```
### Link Buttons
Use the `href` attribute to convert the button to a link.
```html preview
<sl-icon-button name="gear" label="Settings" href="https://example.com" target="_blank"></sl-icon-button>
```
### Icon Button with Tooltip
Wrap a tooltip around an icon button to provide contextual information to the user.
```html preview
<sl-tooltip content="Settings">
<sl-icon-button name="gear" label="Settings"></sl-icon-button>
</sl-tooltip>
```
### Disabled
Use the `disabled` attribute to disable the icon button.
```html preview
<sl-icon-button name="gear" label="Settings" disabled></sl-icon-button>
```
[component-metadata:sl-icon-button]

View File

@@ -2,12 +2,14 @@
[component-header:sl-icon]
Icons are symbols that can be used to represent or provide context to various options and actions within an application.
Icons are symbols that can be used to represent various options within an application.
Shoelace comes bundled with over 1,000 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. Click or tap on an icon below to copy the name and use it like this.
Shoelace comes bundled with over 1,300 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. These icons are part of the `default` icon library. If you prefer, you can register [custom icon libraries](#icon-libraries) as well.
Click or tap on an icon below to copy its name and use it like this.
```html
<sl-icon name="icon-name-here" hidden></sl-icon>
<sl-icon name="icon-name-here"></sl-icon>
```
<div class="icon-search">
@@ -27,7 +29,7 @@ Shoelace comes bundled with over 1,000 icons courtesy of the [Bootstrap Icons](h
## Examples
### Icon Sizes
### Sizing
Icons are sized relative to the current font size. To change their size, set the `font-size` property on the icon itself or on a parent element as shown below.
@@ -54,14 +56,441 @@ Icons are sized relative to the current font size. To change their size, set the
### Custom Icons
Custom icons can be loaded by setting the `src` attribute. Only SVG images are supported
Custom icons can be loaded individually with the `src` attribute. Only SVGs on a local or CORS-enabled endpoint are supported. If you're using more than one custom icon, it might make sense to register a [custom icon library](#icon-libraries).
```html preview
<sl-icon src="/assets/images/shoe.svg" style="font-size: 8rem;"></sl-icon>
```
## Icon Libraries
You can register additional icons to use with the `<sl-icon>` component through icon libraries. Icon files can exist locally or on a CORS-enabled endpoint (e.g. a CDN). There is no limit to how many icon libraries you can register and there is no cost associated with registering them, as individual icons are only requested when they're used.
Shoelace ships with two built-in icon libraries, `default` and `system`. The [default icon library](#customizing-the-default-library) contains all of the icons in the Bootstrap Icons project. The [system icon library](#customizing-the-system-library) contains only a small subset of icons that are used internally by Shoelace components.
To register an additional icon library, use the `registerIconLibrary()` function that's exported from `utilities/icon-library.js`. At a minimum, you must provide a name and a resolver function. The resolver function translates an icon name to a URL where the corresponding SVG file exists. Refer to the examples below to better understand how it works.
If necessary, a mutator function can be used to mutate the SVG element before rendering. This is necessary for some libraries due to the many possible ways SVGs are crafted. For example, icons should ideally inherit the current text color via `currentColor`, so you may need to apply `fill="currentColor` or `stroke="currentColor"` to the SVG element using this function.
Here's an example that registers an icon library located in the `/assets/icons` directory.
```html
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('my-icons', {
resolver: name => `/assets/icons/${name}.svg`,
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
```
To display an icon, set the `library` and `name` attributes of an `<sl-icon>` element.
```html
<!-- This will show the icon located at /assets/icons/smile.svg -->
<sl-icon library="my-icons" name="smile"></sl-icon>
```
If an icon is used before registration occurs, it will be empty initially but shown when registered.
The following examples demonstrate how to register a number of popular, open source icon libraries via CDN. Feel free to adapt the code as you see fit to use your own origin or naming conventions.
### Boxicons
This will register the [Boxicons](https://boxicons.com/) library using the jsDelivr CDN. This library has three variations: regular (`bx-*`), solid (`bxs-*`), and logos (`bxl-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
Icons in this library are licensed under the [Creative Commons 4.0 License](https://github.com/atisawd/boxicons#license).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('boxicons', {
resolver: name => {
let folder = 'regular';
if (name.substring(0, 4) === 'bxs-') folder = 'solid';
if (name.substring(0, 4) === 'bxl-') folder = 'logos';
return `https://cdn.jsdelivr.net/npm/boxicons@2.0.5/svg/${folder}/${name}.svg`;
},
mutator:svg => svg.setAttribute('fill', 'currentColor')
});
</script>
<div style="font-size: 24px;">
<sl-icon library="boxicons" name="bx-bot"></sl-icon>
<sl-icon library="boxicons" name="bx-cookie"></sl-icon>
<sl-icon library="boxicons" name="bx-joystick"></sl-icon>
<sl-icon library="boxicons" name="bx-save"></sl-icon>
<sl-icon library="boxicons" name="bx-server"></sl-icon>
<sl-icon library="boxicons" name="bx-wine"></sl-icon>
<br>
<sl-icon library="boxicons" name="bxs-bot"></sl-icon>
<sl-icon library="boxicons" name="bxs-cookie"></sl-icon>
<sl-icon library="boxicons" name="bxs-joystick"></sl-icon>
<sl-icon library="boxicons" name="bxs-save"></sl-icon>
<sl-icon library="boxicons" name="bxs-server"></sl-icon>
<sl-icon library="boxicons" name="bxs-wine"></sl-icon>
<br>
<sl-icon library="boxicons" name="bxl-apple"></sl-icon>
<sl-icon library="boxicons" name="bxl-chrome"></sl-icon>
<sl-icon library="boxicons" name="bxl-edge"></sl-icon>
<sl-icon library="boxicons" name="bxl-firefox"></sl-icon>
<sl-icon library="boxicons" name="bxl-opera"></sl-icon>
<sl-icon library="boxicons" name="bxl-microsoft"></sl-icon>
</div>
```
### Feather Icons
This will register the [Feather Icons](https://feathericons.com/) library using the jsDelivr CDN.
Icons in this library are licensed under the [MIT License](https://github.com/feathericons/feather/blob/master/LICENSE).
```html preview
<div style="font-size: 24px;">
<sl-icon library="feather" name="feather"></sl-icon>
<sl-icon library="feather" name="pie-chart"></sl-icon>
<sl-icon library="feather" name="settings"></sl-icon>
<sl-icon library="feather" name="map-pin"></sl-icon>
<sl-icon library="feather" name="printer"></sl-icon>
<sl-icon library="feather" name="shopping-cart"></sl-icon>
</div>
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('feather', {
resolver: name => `https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/icons/${name}.svg`
});
</script>
```
### Font Awesome
This will register the [Font Awesome Free](https://fontawesome.com/) library using the jsDelivr CDN. This library has three variations: regular (`far-*`), solid (`fas-*`), and brands (`fab-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
Icons in this library are licensed under the [Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt). Some of the icons that appear on the Font Awesome website require a license and are therefore not available in the CDN.
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('fa', {
resolver: name => {
const filename = name.replace(/^fa[rbs]-/, '');
let folder = 'regular';
if (name.substring(0, 4) === 'fas-') folder = 'solid';
if (name.substring(0, 4) === 'fab-') folder = 'brands';
return `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.1/svgs/${folder}/${filename}.svg`;
},
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
<div style="font-size: 24px;">
<sl-icon library="fa" name="far-bell"></sl-icon>
<sl-icon library="fa" name="far-comment"></sl-icon>
<sl-icon library="fa" name="far-hand-point-right"></sl-icon>
<sl-icon library="fa" name="far-hdd"></sl-icon>
<sl-icon library="fa" name="far-heart"></sl-icon>
<sl-icon library="fa" name="far-star"></sl-icon>
<br>
<sl-icon library="fa" name="fas-archive"></sl-icon>
<sl-icon library="fa" name="fas-book"></sl-icon>
<sl-icon library="fa" name="fas-chess-knight"></sl-icon>
<sl-icon library="fa" name="fas-dice"></sl-icon>
<sl-icon library="fa" name="fas-pizza-slice"></sl-icon>
<sl-icon library="fa" name="fas-scroll"></sl-icon>
<br>
<sl-icon library="fa" name="fab-apple"></sl-icon>
<sl-icon library="fa" name="fab-chrome"></sl-icon>
<sl-icon library="fa" name="fab-edge"></sl-icon>
<sl-icon library="fa" name="fab-firefox"></sl-icon>
<sl-icon library="fa" name="fab-opera"></sl-icon>
<sl-icon library="fa" name="fab-microsoft"></sl-icon>
</div>
```
### Heroicons
This will register the [Heroicons](https://heroicons.com/) library using the jsDelivr CDN.
Icons in this library are licensed under the [MIT License](https://github.com/tailwindlabs/heroicons/blob/master/LICENSE).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('heroicons', {
resolver: name => `https://cdn.jsdelivr.net/npm/heroicons@0.4.2/outline/${name}.svg`
});
</script>
<div style="font-size: 24px;">
<sl-icon library="heroicons" name="chat"></sl-icon>
<sl-icon library="heroicons" name="cloud"></sl-icon>
<sl-icon library="heroicons" name="cog"></sl-icon>
<sl-icon library="heroicons" name="document-text"></sl-icon>
<sl-icon library="heroicons" name="gift"></sl-icon>
<sl-icon library="heroicons" name="volume-up"></sl-icon>
</div>
```
### Iconoir
This will register the [Iconoir](https://iconoir.com/) library using the jsDelivr CDN.
Icons in this library are licensed under the [MIT License](https://github.com/lucaburgio/iconoir/blob/master/LICENSE).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('iconoir', {
resolver: name => `https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@latest/icons/${name}.svg`
});
</script>
<div style="font-size: 24px;">
<sl-icon library="iconoir" name="check-circled-outline"></sl-icon>
<sl-icon library="iconoir" name="drawer"></sl-icon>
<sl-icon library="iconoir" name="keyframes"></sl-icon>
<sl-icon library="iconoir" name="headset-help"></sl-icon>
<sl-icon library="iconoir" name="color-picker"></sl-icon>
<sl-icon library="iconoir" name="wifi"></sl-icon>
</div>
```
### Ionicons
This will register the [Ionicons](https://ionicons.com/) library using the jsDelivr CDN. This library has three variations: outline (default), filled (`*-filled`), and sharp (`*-sharp`). A mutator function is required to polyfill a handful of styles we're not including.
Icons in this library are licensed under the [MIT License](https://github.com/ionic-team/ionicons/blob/master/LICENSE).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('ionicons', {
resolver: name => `https://cdn.jsdelivr.net/npm/ionicons@5.1.2/dist/ionicons/svg/${name}.svg`,
mutator: svg => {
svg.setAttribute('fill', 'currentColor');
svg.setAttribute('stroke', 'currentColor');
[...svg.querySelectorAll('.ionicon-fill-none')].map(el => el.setAttribute('fill', 'none'));
[...svg.querySelectorAll('.ionicon-stroke-width')].map(el => el.setAttribute('stroke-width', '32px'));
}
});
</script>
<div style="font-size: 24px;">
<sl-icon library="ionicons" name="alarm"></sl-icon>
<sl-icon library="ionicons" name="american-football"></sl-icon>
<sl-icon library="ionicons" name="bug"></sl-icon>
<sl-icon library="ionicons" name="chatbubble"></sl-icon>
<sl-icon library="ionicons" name="settings"></sl-icon>
<sl-icon library="ionicons" name="warning"></sl-icon>
<br>
<sl-icon library="ionicons" name="alarm-outline"></sl-icon>
<sl-icon library="ionicons" name="american-football-outline"></sl-icon>
<sl-icon library="ionicons" name="bug-outline"></sl-icon>
<sl-icon library="ionicons" name="chatbubble-outline"></sl-icon>
<sl-icon library="ionicons" name="settings-outline"></sl-icon>
<sl-icon library="ionicons" name="warning-outline"></sl-icon>
<br>
<sl-icon library="ionicons" name="alarm-sharp"></sl-icon>
<sl-icon library="ionicons" name="american-football-sharp"></sl-icon>
<sl-icon library="ionicons" name="bug-sharp"></sl-icon>
<sl-icon library="ionicons" name="chatbubble-sharp"></sl-icon>
<sl-icon library="ionicons" name="settings-sharp"></sl-icon>
<sl-icon library="ionicons" name="warning-sharp"></sl-icon>
</div>
```
### Jam Icons
This will register the [Jam Icons](https://jam-icons.com/) library using the jsDelivr CDN. This library has two variations: regular (default) and filled (`*-f`). A mutator function is required to set the SVG's `fill` to `currentColor`.
Icons in this library are licensed under the [MIT License](https://github.com/michaelampr/jam/blob/master/LICENSE).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('jam', {
resolver: name => `https://cdn.jsdelivr.net/npm/jam-icons@2.0.0/svg/${name}.svg`,
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
<div style="font-size: 24px;">
<sl-icon library="jam" name="calendar"></sl-icon>
<sl-icon library="jam" name="camera"></sl-icon>
<sl-icon library="jam" name="filter"></sl-icon>
<sl-icon library="jam" name="leaf"></sl-icon>
<sl-icon library="jam" name="picture"></sl-icon>
<sl-icon library="jam" name="set-square"></sl-icon>
<br>
<sl-icon library="jam" name="calendar-f"></sl-icon>
<sl-icon library="jam" name="camera-f"></sl-icon>
<sl-icon library="jam" name="filter-f"></sl-icon>
<sl-icon library="jam" name="leaf-f"></sl-icon>
<sl-icon library="jam" name="picture-f"></sl-icon>
<sl-icon library="jam" name="set-square-f"></sl-icon>
</div>
```
### Material Icons
This will register the [Material Icons](https://material.io/resources/icons/?style=baseline) library using the jsDelivr CDN. This library has three variations: outline (default), round (`*_round`), and sharp (`*_sharp`). A mutator function is required to set the SVG's `fill` to `currentColor`.
Icons in this library are licensed under the [Apache 2.0 License](https://github.com/google/material-design-icons/blob/master/LICENSE).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('material', {
resolver: name => {
const match = name.match(/^(.*?)(_(round|sharp))?$/);
return `https://cdn.jsdelivr.net/npm/@material-icons/svg@1.0.5/svg/${match[1]}/${match[3] || 'outline'}.svg`;
},
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
<div style="font-size: 24px;">
<sl-icon library="material" name="notifications"></sl-icon>
<sl-icon library="material" name="email"></sl-icon>
<sl-icon library="material" name="delete"></sl-icon>
<sl-icon library="material" name="volume_up"></sl-icon>
<sl-icon library="material" name="settings"></sl-icon>
<sl-icon library="material" name="shopping_basket"></sl-icon>
<br>
<sl-icon library="material" name="notifications_round"></sl-icon>
<sl-icon library="material" name="email_round"></sl-icon>
<sl-icon library="material" name="delete_round"></sl-icon>
<sl-icon library="material" name="volume_up_round"></sl-icon>
<sl-icon library="material" name="settings_round"></sl-icon>
<sl-icon library="material" name="shopping_basket_round"></sl-icon>
<br>
<sl-icon library="material" name="notifications_sharp"></sl-icon>
<sl-icon library="material" name="email_sharp"></sl-icon>
<sl-icon library="material" name="delete_sharp"></sl-icon>
<sl-icon library="material" name="volume_up_sharp"></sl-icon>
<sl-icon library="material" name="settings_sharp"></sl-icon>
<sl-icon library="material" name="shopping_basket_sharp"></sl-icon>
</div>
```
### Remix Icon
This will register the [Remix Icon](https://remixicon.com/) library using the jsDelivr CDN. This library groups icons by categories, so the name must include the category and icon separated by a slash, as well as the `-line` or `-fill` suffix as needed. A mutator function is required to set the SVG's `fill` to `currentColor`.
Icons in this library are licensed under the [Apache 2.0 License](https://github.com/Remix-Design/RemixIcon/blob/master/License).
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('remixicon', {
resolver: name => {
const match = name.match(/^(.*?)\/(.*?)?$/);
match[1] = match[1].charAt(0).toUpperCase() + match[1].slice(1);
return `https://cdn.jsdelivr.net/npm/remixicon@2.5.0/icons/${match[1]}/${match[2]}.svg`;
},
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
<div style="font-size: 24px;">
<sl-icon library="remixicon" name="business/cloud-line"></sl-icon>
<sl-icon library="remixicon" name="design/brush-line"></sl-icon>
<sl-icon library="remixicon" name="business/pie-chart-line"></sl-icon>
<sl-icon library="remixicon" name="development/bug-line"></sl-icon>
<sl-icon library="remixicon" name="media/image-line"></sl-icon>
<sl-icon library="remixicon" name="system/alert-line"></sl-icon>
<br>
<sl-icon library="remixicon" name="business/cloud-fill"></sl-icon>
<sl-icon library="remixicon" name="design/brush-fill"></sl-icon>
<sl-icon library="remixicon" name="business/pie-chart-fill"></sl-icon>
<sl-icon library="remixicon" name="development/bug-fill"></sl-icon>
<sl-icon library="remixicon" name="media/image-fill"></sl-icon>
<sl-icon library="remixicon" name="system/alert-fill"></sl-icon>
</div>
```
### Unicons
This will register the [Unicons](https://iconscout.com/unicons) library using the jsDelivr CDN. This library has two variations: line (default) and solid (`*-s`). A mutator function is required to set the SVG's `fill` to `currentColor`.
Icons in this library are licensed under the [Apache 2.0 License](https://github.com/Iconscout/unicons/blob/master/LICENSE). Some of the icons that appear on the Unicons website, particularly many of the solid variations, require a license and are therefore not available in the CDN.
```html preview
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('unicons', {
resolver: name => {
const match = name.match(/^(.*?)(-s)?$/);
return `https://cdn.jsdelivr.net/npm/@iconscout/unicons@3.0.3/svg/${match[2] === '-s' ? 'solid' : 'line'}/${match[1]}.svg`;
},
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
<div style="font-size: 24px;">
<sl-icon library="unicons" name="clock"></sl-icon>
<sl-icon library="unicons" name="graph-bar"></sl-icon>
<sl-icon library="unicons" name="padlock"></sl-icon>
<sl-icon library="unicons" name="polygon"></sl-icon>
<sl-icon library="unicons" name="rocket"></sl-icon>
<sl-icon library="unicons" name="star"></sl-icon>
<br>
<sl-icon library="unicons" name="clock-s"></sl-icon>
<sl-icon library="unicons" name="graph-bar-s"></sl-icon>
<sl-icon library="unicons" name="padlock-s"></sl-icon>
<sl-icon library="unicons" name="polygon-s"></sl-icon>
<sl-icon library="unicons" name="rocket-s"></sl-icon>
<sl-icon library="unicons" name="star-s"></sl-icon>
</div>
```
### Customizing the Default Library
The default icon library contains over 1,300 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. These are the icons that display when you use `<sl-icon>` without the `library` attribute. If you prefer to have these icons resolve elsewhere or to a different icon library, register an icon library using the `default` name and a custom resolver.
This example will load the same set of icons from the jsDelivr CDN instead of your local assets folder.
```html
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('default', {
resolver: name => `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.0.0/icons/${name}.svg`
});
</script>
```
### Customizing the System Library
The system library contains only the icons used internally by Shoelace components. Unlike the default icon library, the system library does not rely on physical assets. Instead, its icons are hard-coded as data URIs into the resolver to ensure their availability.
If you want to change the icons Shoelace uses internally, you can register an icon library using the `system` name and a custom resolver. If you choose to do this, it's your responsibility to provide all of the icons that are required by components. You can reference `src/components/library.system.ts` for a complete list of system icons used by Shoelace.
```html
<script type="module">
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
registerIconLibrary('system', {
resolver: name => `/path/to/custom/icons/${name}.svg`
});
</script>
```
<!-- Supporting scripts and styles for the search utility -->
<script>
fetch('/dist/shoelace/icons/icons.json')
fetch('/dist/assets/icons/icons.json')
.then(res => res.json())
.then(icons => {
const container = document.querySelector('.icon-search');
@@ -71,6 +500,7 @@ Custom icons can be loaded by setting the `src` attribute. Only SVG images are s
const loader = container.querySelector('.icon-loader');
const list = container.querySelector('.icon-list');
const queue = [];
let inputTimeout;
// Generate icons
icons.map(i => {
@@ -100,23 +530,26 @@ Custom icons can be loaded by setting the `src` attribute. Only SVG images are s
});
// Filter as the user types
input.addEventListener('slInput', () => {
[...list.querySelectorAll('.icon-list-item')].map(item => {
const filter = input.value.toLowerCase();
if (filter === '') {
item.hidden = false;
} else {
const terms = item.getAttribute('data-terms').toLowerCase();
item.hidden = terms.indexOf(filter) < 0;
}
});
input.addEventListener('sl-input', () => {
clearTimeout(inputTimeout);
inputTimeout = setTimeout(() => {
[...list.querySelectorAll('.icon-list-item')].map(item => {
const filter = input.value.toLowerCase();
if (filter === '') {
item.hidden = false;
} else {
const terms = item.getAttribute('data-terms').toLowerCase();
item.hidden = terms.indexOf(filter) < 0;
}
});
}, 250);
});
// Sort by type and remember preference
const iconType = localStorage.getItem('sl-icon:type') || 'outline';
select.value = iconType;
list.setAttribute('data-type', select.value);
select.addEventListener('slChange', () => {
select.addEventListener('sl-change', () => {
list.setAttribute('data-type', select.value);
localStorage.setItem('sl-icon:type', select.value);
});
@@ -125,11 +558,15 @@ Custom icons can be loaded by setting the `src` attribute. Only SVG images are s
<style>
.icon-search {
border: solid 1px var(--sl-color-gray-90);
border: solid 1px rgb(var(--sl-panel-border-color));
border-radius: var(--sl-border-radius-medium);
padding: var(--sl-spacing-medium);
}
.icon-search [hidden] {
display: none;
}
.icon-search-controls {
display: flex;
}
@@ -139,6 +576,7 @@ Custom icons can be loaded by setting the `src` attribute. Only SVG images are s
}
.icon-search-controls sl-select {
width: 10rem;
flex: 0 0 auto;
margin-left: 1rem;
}
@@ -166,18 +604,18 @@ Custom icons can be loaded by setting the `src` attribute. Only SVG images are s
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--sl-border-radius-circle);
border-radius: var(--sl-border-radius-medium);
font-size: 24px;
width: 2em;
height: 2em;
margin: 0 auto;
cursor: pointer;
cursor: copy;
transition: var(--sl-transition-medium) all;
}
.icon-list-item:hover {
background-color: var(--sl-color-primary-95);
color: var(--sl-color-primary-50);
background-color: rgb(var(--sl-color-primary-50));
color: rgb(var(--sl-color-primary-600));
}
.icon-list[data-type="outline"] .icon-list-item[data-name$="-fill"] {
@@ -195,22 +633,22 @@ Custom icons can be loaded by setting the `src` attribute. Only SVG images are s
}
@media screen and (max-width: 1000px) {
.icon-search-controls {
display: block;
}
.icon-search-controls sl-select {
margin-left: 0;
margin-top: 1rem;
}
.icon-list {
grid-template-columns: repeat(8, 1fr);
}
.icon-list-item {
font-size: 20px;
}
}
.icon-search-controls {
display: block;
}
.icon-search-controls sl-select {
width: auto;
margin: 1rem 0 0 0;
}
}
@media screen and (max-width: 500px) {

View File

@@ -0,0 +1,29 @@
# Image Comparer
[component-header:sl-image-comparer]
Compare visual differences between similar photos with a sliding panel.
For best results, use images that share the same dimensions. The slider can be controlled by dragging or pressing the left and right arrow keys. (Tip: press shift + arrows to move the slider in larger intervals, or home + end to jump to the beginning or end.)
```html preview
<sl-image-comparer>
<img slot="before" src="https://images.unsplash.com/photo-1517331156700-3c241d2b4d83?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&sat=-100&bri=-5" alt="Grayscale version of kittens in a basket looking around.">
<img slot="after" src="https://images.unsplash.com/photo-1517331156700-3c241d2b4d83?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80" alt="Color version of kittens in a basket looking around.">
</sl-image-comparer>
```
## Examples
### Initial Position
Use the `position` attribute to set the initial position of the slider. This is a percentage from `0` to `100`.
```html preview
<sl-image-comparer position="25">
<img slot="before" src="https://images.unsplash.com/photo-1520903074185-8eca362b3dce?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1200&q=80" alt="A person sitting on bricks wearing untied boots.">
<img slot="after" src="https://images.unsplash.com/photo-1520640023173-50a135e35804?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80" alt="A person sitting on a yellow curb tying shoelaces on a boot.">
</sl-image-comparer>
```
[component-metadata:sl-image-comparer]

View File

@@ -0,0 +1,39 @@
# Include
[component-header:sl-include]
Includes give you the power to embed external HTML files into the page.
Included files are asynchronously requested using `window.fetch()`. Requests are cached, so the same file can be included multiple times, but only one request will be made.
The included content will be inserted into the `<sl-include>` element's default slot so it can be easily accessed and styled through the light DOM.
```html preview no-codepen
<sl-include src="/assets/examples/include.html"></sl-include>
```
## Examples
### Listening for Events
When an include file loads successfully, the `sl-load` event will be emitted. You can listen for this event to add custom loading logic to your includes.
If the request fails, the `sl-error` event will be emitted. In this case, `event.detail.status` will contain the resulting HTTP status code of the request, e.g. 404 (not found).
```html
<sl-include src="/assets/examples/include.html"></sl-include>
<script>
const include = document.querySelector('sl-include');
include.addEventListener('sl-load', () => {
console.log('Success');
});
include.addEventListener('sl-error', event => {
console.log('Error', event.detail.status);
});
</script>
```
[component-metadata:sl-include]

View File

@@ -8,31 +8,13 @@ Inputs collect data from the user.
<sl-input></sl-input>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
?> Please refer to the section on [form control validation](/components/form?id=form-control-validation) to learn how to do client-side validation.
## Examples
### Labels
Use the `label` attribute to give the input an accessible label.
```html preview
<sl-input label="Name"></sl-input>
<br>
<sl-input type="email" label="Email" placeholder="bob@example.com"></sl-input>
```
### Help Text
Add descriptive help text to an input with the `help-text` slot.
```html preview
<sl-input label="Nickname">
<div slot="help-text">What would you like people to call you?</div>
</sl-input>
```
### Placeholder
### Placeholders
Use the `placeholder` attribute to add a placeholder.
@@ -40,21 +22,37 @@ Use the `placeholder` attribute to add a placeholder.
<sl-input placeholder="Type something"></sl-input>
```
### Size
### Clearable
Use the `size` attribute to change an input's size.
Add the `clearable` attribute to add a clear button when the input has content.
```html preview
<sl-input placeholder="Small" size="small"></sl-input>
<sl-input placeholder="Clearable" clearable></sl-input>
```
### Toggle Password
Add the `toggle-password` attribute to add a toggle button that will show the password when activated.
```html preview
<sl-input type="password" placeholder="Password Toggle" size="small" toggle-password></sl-input>
<br>
<sl-input placeholder="Medium" size="medium"></sl-input>
<sl-input type="password" placeholder="Password Toggle" size="medium" toggle-password></sl-input>
<br>
<sl-input placeholder="Large" size="large"></sl-input>
<sl-input type="password" placeholder="Password Toggle" size="large" toggle-password></sl-input>
```
### Filled Inputs
Add the `filled` attribute to draw a filled input.
```html preview
<sl-input placeholder="Type something" filled></sl-input>
```
### Pill
Use the `pill` prop to give inputs rounded edges.
Use the `pill` attribute to give inputs rounded edges.
```html preview
<sl-input placeholder="Small" size="small" pill></sl-input>
@@ -64,49 +62,16 @@ Use the `pill` prop to give inputs rounded edges.
<sl-input placeholder="Large" size="large" pill></sl-input>
```
### Prefix & Suffix Icons
### Input Types
Use the `prefix` and `suffix` slots to add icons.
The `type` attribute controls the type of input the browser renders.
```html preview
<sl-input placeholder="Small" size="small">
<sl-icon name="tag" slot="prefix"></sl-icon>
<sl-icon name="gear" slot="suffix"></sl-icon>
</sl-input>
<sl-input type="email" Placeholder="Email"></sl-input>
<br>
<sl-input placeholder="Medium" size="medium">
<sl-icon name="tag" slot="prefix"></sl-icon>
<sl-icon name="gear" slot="suffix"></sl-icon>
</sl-input>
<sl-input type="number" Placeholder="Number"></sl-input>
<br>
<sl-input placeholder="Large" size="large">
<sl-icon name="tag" slot="prefix"></sl-icon>
<sl-icon name="gear" slot="suffix"></sl-icon>
</sl-input>
```
### Clearable
Add the `clearable` prop to add a clear button when the input has content.
```html preview
<sl-input placeholder="Clearable" size="small" clearable></sl-input>
<br>
<sl-input placeholder="Clearable" size="medium" clearable></sl-input>
<br>
<sl-input placeholder="Clearable" size="large" clearable></sl-input>
```
### Toggle Password
Add the `toggle-password` prop to add a toggle button that will show the password when activated.
```html preview
<sl-input type="password" placeholder="Password Toggle" size="small" toggle-password></sl-input>
<br>
<sl-input type="password" placeholder="Password Toggle" size="medium" toggle-password></sl-input>
<br>
<sl-input type="password" placeholder="Password Toggle" size="large" toggle-password></sl-input>
<sl-input type="date" Placeholder="Date"></sl-input>
```
### Disabled
@@ -121,20 +86,56 @@ Use the `disabled` attribute to disable an input.
<sl-input placeholder="Disabled" size="large" disabled></sl-input>
```
### Validation
### Sizes
Show a valid or invalid state by setting the `valid` and `invalid` attributes, respectively. Help text can be used to provide feedback for validation and will be styled accordingly.
Use the `size` attribute to change an input's size.
```html preview
<sl-input label="Valid" valid>
<div slot="help-text">This is a valid input</div>
</sl-input>
<sl-input placeholder="Small" size="small"></sl-input>
<br>
<sl-input placeholder="Medium" size="medium"></sl-input>
<br>
<sl-input placeholder="Large" size="large"></sl-input>
```
<sl-input label="Invalid" invalid>
<div slot="help-text">This is an invalid input</div>
### Prefix & Suffix Icons
Use the `prefix` and `suffix` slots to add icons.
```html preview
<sl-input placeholder="Small" size="small">
<sl-icon name="house" slot="prefix"></sl-icon>
<sl-icon name="chat" slot="suffix"></sl-icon>
</sl-input>
<br>
<sl-input placeholder="Medium" size="medium">
<sl-icon name="house" slot="prefix"></sl-icon>
<sl-icon name="chat" slot="suffix"></sl-icon>
</sl-input>
<br>
<sl-input placeholder="Large" size="large">
<sl-icon name="house" slot="prefix"></sl-icon>
<sl-icon name="chat" slot="suffix"></sl-icon>
</sl-input>
```
### Labels
Use the `label` attribute to give the input an accessible label. For labels that contain HTML, use the `label` slot instead.
```html preview
<sl-input label="What is your name?"></sl-input>
```
### Help Text
Add descriptive help text to an input with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
```html preview
<sl-input
label="Nickname"
help-text="What would you like people to call you?"
></sl-input>
```
[component-metadata:sl-input]

View File

@@ -1,22 +0,0 @@
# Menu Divider
[component-header:sl-menu-divider]
Menu dividers are used to visually group menu items.
```html preview
<sl-menu
style="max-width: 200px; border: solid 1px var(--sl-color-gray-90); border-radius: var(--sl-border-radius-medium);"
>
<sl-menu-item value="1">Option 1</sl-menu-item>
<sl-menu-item value="2">Option 2</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-menu-item value="3">Option 3</sl-menu-item>
<sl-menu-item value="4">Option 4</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-menu-item value="5">Option 5</sl-menu-item>
<sl-menu-item value="6">Option 6</sl-menu-item>
</sl-menu>
```
[component-metadata:sl-menu-divider]

View File

@@ -5,16 +5,14 @@
Menu items provide options for the user to pick from in a menu.
```html preview
<sl-menu
style="max-width: 200px; border: solid 1px var(--sl-color-gray-90); border-radius: var(--sl-border-radius-medium);"
>
<sl-menu style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item>Option 1</sl-menu-item>
<sl-menu-item>Option 2</sl-menu-item>
<sl-menu-item>Option 3</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item checked>Checked</sl-menu-item>
<sl-menu-item disabled>Disabled</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item>
Prefix Icon
<sl-icon slot="prefix" name="gift"></sl-icon>
@@ -26,4 +24,82 @@ Menu items provide options for the user to pick from in a menu.
</sl-menu>
```
## Examples
### Checked
Use the `checked` attribute to draw menu items in a checked state.
```html preview
<sl-menu style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item>Option 1</sl-menu-item>
<sl-menu-item checked>Option 2</sl-menu-item>
<sl-menu-item>Option 3</sl-menu-item>
</sl-menu>
```
### Disabled
Add the `disabled` attribute to disable the menu item so it cannot be selected.
```html preview
<sl-menu style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item>Option 1</sl-menu-item>
<sl-menu-item disabled>Option 2</sl-menu-item>
<sl-menu-item>Option 3</sl-menu-item>
</sl-menu>
```
### Prefix & Suffix
Add content to the start and end of menu items using the `prefix` and `suffix` slots.
```html preview
<sl-menu style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item>
<sl-icon slot="prefix" name="house"></sl-icon>
Home
</sl-menu-item>
<sl-menu-item>
<sl-icon slot="prefix" name="envelope"></sl-icon>
Messages
<sl-badge slot="suffix" type="primary" pill>12</sl-badge>
</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item>
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
</sl-menu-item>
</sl-menu>
```
### Value & Selection
The `value` attribute can be used to assign a hidden value, such as a unique identifier, to a menu item. When an item is selected, the `sl-select` event will be emitted and a reference to the item will be available at `event.detail.item`. You can use this reference to access the selected item's value, its checked state, and more.
```html preview
<sl-menu class="menu-value" style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item value="opt-1">Option 1</sl-menu-item>
<sl-menu-item value="opt-2">Option 2</sl-menu-item>
<sl-menu-item value="opt-3">Option 3</sl-menu-item>
</sl-menu>
<script>
const menu = document.querySelector('.menu-value');
menu.addEventListener('sl-select', event => {
const item = event.detail.item;
// Toggle checked state
item.checked = !item.checked;
// Log value
console.log(`Selected value: ${item.value}`);
});
</script>
```
[component-metadata:sl-menu-item]

View File

@@ -6,13 +6,13 @@ Menu labels are used to describe a group of menu items.
```html preview
<sl-menu
style="max-width: 200px; border: solid 1px var(--sl-color-gray-90); border-radius: var(--sl-border-radius-medium);"
style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);"
>
<sl-menu-label>Fruits</sl-menu-label>
<sl-menu-item value="apple">Apple</sl-menu-item>
<sl-menu-item value="banana">Banana</sl-menu-item>
<sl-menu-item value="orange">Orange</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-label>Vegetables</sl-menu-label>
<sl-menu-item value="broccoli">Broccoli</sl-menu-item>
<sl-menu-item value="carrot">Carrot</sl-menu-item>

View File

@@ -2,17 +2,15 @@
[component-header:sl-menu]
Menus provide a list of options for the user.
Menus provide a list of options for the user to choose from.
Use [menu items](/components/menu-item.md), [menu dividers](/components/menu-divider.md), and [menu labels](/components/menu-label.md) to compose a menu.
You can use [menu items](/components/menu-item), [menu labels](/components/menu-label), and [dividers](/components/divider) to compose a menu. Menus support keyboard interactions, including type-to-select an option.
```html preview
<sl-menu
style="max-width: 200px; border: solid 1px var(--sl-color-gray-90); border-radius: var(--sl-border-radius-medium);"
>
<sl-menu style="max-width: 200px; border: solid 1px rgb(var(--sl-panel-border-color)); border-radius: var(--sl-border-radius-medium);">
<sl-menu-item value="undo">Undo</sl-menu-item>
<sl-menu-item value="redo">Redo</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item value="cut">Cut</sl-menu-item>
<sl-menu-item value="copy">Copy</sl-menu-item>
<sl-menu-item value="paste">Paste</sl-menu-item>
@@ -20,4 +18,6 @@ Use [menu items](/components/menu-item.md), [menu dividers](/components/menu-div
</sl-menu>
```
?> Menus are intended for system menus (dropdown menus, select menus, context menus, etc.). They should not be mistaken for navigation menus which serve a different purpose and have a different semantic meaning. If you're building navigation, use `<nav>` and `<a>` elements instead.
[component-metadata:sl-menu]

View File

@@ -0,0 +1,104 @@
# Mutation Observer
[component-header:sl-mutation-observer]
The Mutation Observer component offers a thin, declarative interface to the [`MutationObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).
The mutation observer will report changes to the content it wraps through the `sl-mutation` event. When emitted, a collection of [MutationRecord](https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord) objects will be attached to `event.detail` that contains information about how it changed.
```html preview
<div class="mutation-overview">
<sl-mutation-observer attr>
<sl-button type="primary">Click to mutate</sl-button>
</sl-mutation-observer>
<br>
👆 Click the button and watch the console
<script>
const container = document.querySelector('.mutation-overview');
const mutationObserver = container.querySelector('sl-mutation-observer');
const button = container.querySelector('sl-button');
const types = ['primary', 'success', 'neutral', 'warning', 'danger'];
let clicks = 0;
// Change the button's type attribute
button.addEventListener('click', () => {
clicks++;
button.setAttribute('type', types[clicks % types.length]);
});
// Log mutations
mutationObserver.addEventListener('sl-mutation', event => {
console.log(event.detail);
});
</script>
<style>
.mutation-overview sl-button {
margin-bottom: 1rem;
}
</style>
</div>
```
?> When you create a mutation observer, you must indicate what changes it should respond to by including at least one of `attr`, `child-list`, or `char-data`. If you don't specify at least one of these attributes, no mutation events will be emitted.
## Examples
### Child List
Use the `child-list` attribute to watch for new child elements that are added or removed.
```html preview
<div class="mutation-child-list">
<sl-mutation-observer child-list>
<div class="buttons">
<sl-button type="primary">Add button</sl-button>
</div>
</sl-mutation-observer>
👆 Add and remove buttons and watch the console
<script>
const container = document.querySelector('.mutation-child-list');
const mutationObserver = container.querySelector('sl-mutation-observer');
const buttons = container.querySelector('.buttons');
const button = container.querySelector('sl-button[type="primary"]');
let i = 0;
// Add a button
button.addEventListener('click', () => {
const button = document.createElement('sl-button');
button.textContent = ++i;
buttons.append(button);
});
// Remove a button
buttons.addEventListener('click', event => {
const target = event.target.closest('sl-button:not([type="primary"])');
event.stopPropagation();
if (target) {
target.remove();
}
});
// Log mutations
mutationObserver.addEventListener('sl-mutation', event => {
console.log(event.detail);
});
</script>
<style>
.mutation-child-list .buttons {
display: flex;
gap: .25rem;
flex-wrap: wrap;
margin-bottom: 1rem;
}
</style>
</div>
```
[component-metadata:sl-mutation-observer]

View File

@@ -2,10 +2,10 @@
[component-header:sl-progress-bar]
Progress bars are used to show the progress of a determinate operation.
Progress bars are used to show the status of an ongoing operation.
```html preview
<sl-progress-bar percentage="50"></sl-progress-bar>
<sl-progress-bar value="50"></sl-progress-bar>
```
## Examples
@@ -15,15 +15,23 @@ Progress bars are used to show the progress of a determinate operation.
Use the `--height` custom property to set the progress bar's height.
```html preview
<sl-progress-bar percentage="50" style="--height: 6px;"></sl-progress-bar>
<sl-progress-bar value="50" style="--height: 6px;"></sl-progress-bar>
```
### Labels
Use the default slot to show a label.
Use the `label` attribute to label the progress bar and tell assistive devices how to announce it.
```html preview
<sl-progress-bar percentage="50" class="progress-bar-labels">50%</sl-progress-bar>
<sl-progress-bar value="50" label="Upload progress"></sl-progress-bar>
```
### Showing Values
Use the default slot to show a value.
```html preview
<sl-progress-bar value="50" class="progress-bar-values">50%</sl-progress-bar>
<br>
@@ -31,22 +39,30 @@ Use the default slot to show a label.
<sl-button circle><sl-icon name="plus"></sl-icon></sl-button>
<script>
const progressBar = document.querySelector('.progress-bar-labels');
const progressBar = document.querySelector('.progress-bar-values');
const subtractButton = progressBar.nextElementSibling.nextElementSibling;
const addButton = subtractButton.nextElementSibling;
addButton.addEventListener('click', () => {
const percentage = Math.min(100, progressBar.percentage + 10);
progressBar.percentage = percentage;
progressBar.textContent = `${percentage}%`;
const value = Math.min(100, progressBar.value + 10);
progressBar.value = value;
progressBar.textContent = `${value}%`;
});
subtractButton.addEventListener('click', () => {
const percentage = Math.max(0, progressBar.percentage - 10)
progressBar.percentage = percentage;
progressBar.textContent = `${percentage}%`;
const value = Math.max(0, progressBar.value - 10)
progressBar.value = value;
progressBar.textContent = `${value}%`;
});
</script>
```
### Indeterminate
The `indeterminate` attribute can be used to inform the user that the operation is pending, but its status cannot currently be determined. In this state, `value` is ignored and the label, if present, will not be shown.
```html preview
<sl-progress-bar indeterminate></sl-progress-bar>
```
[component-metadata:sl-progress-bar]

View File

@@ -5,25 +5,25 @@
Progress rings are used to show the progress of a determinate operation in a circular fashion.
```html preview
<sl-progress-ring percentage="50"></sl-progress-ring>
<sl-progress-ring value="25"></sl-progress-ring>
```
## Examples
### Size
Use the `size` attribute to set the diameter of the progress ring.
Use the `--size` custom property to set the diameter of the progress ring.
```html preview
<sl-progress-ring percentage="50" size="200"></sl-progress-ring>
<sl-progress-ring value="50" style="--size: 200px;"></sl-progress-ring>
```
### Stroke Width
### Track Width
Use the `stroke-width` attribute to set the width of the progress ring's indicator.
Use the `--track-width` custom property to set the width of the progress ring's track.
```html preview
<sl-progress-ring percentage="50" stroke-width="10"></sl-progress-ring>
<sl-progress-ring value="50" style="--track-width: 10px;"></sl-progress-ring>
```
### Colors
@@ -32,17 +32,28 @@ To change the color, use the `--track-color` and `--indicator-color` custom prop
```html preview
<sl-progress-ring
percentage="50"
style="--track-color: #ffe2c6; --indicator-color: tomato;"
value="50"
style="
--track-color: pink;
--indicator-color: deeppink;
"
></sl-progress-ring>
```
### Labels
Use the `label` attribute to label the progress ring and tell assistive devices how to announce it.
```html preview
<sl-progress-ring value="50" label="Upload progress"></sl-progress-ring>
```
### Showing Values
Use the default slot to show a label.
```html preview
<sl-progress-ring percentage="50" size="200" class="progress-ring-labels" style="margin-bottom: .5rem;">50%</sl-progress-ring>
<sl-progress-ring value="50" class="progress-ring-values" style="margin-bottom: .5rem;">50%</sl-progress-ring>
<br>
@@ -50,20 +61,20 @@ Use the default slot to show a label.
<sl-button circle><sl-icon name="plus"></sl-icon></sl-button>
<script>
const progressRing = document.querySelector('.progress-ring-labels');
const progressRing = document.querySelector('.progress-ring-values');
const subtractButton = progressRing.nextElementSibling.nextElementSibling;
const addButton = subtractButton.nextElementSibling;
addButton.addEventListener('click', () => {
const percentage = Math.min(100, progressRing.percentage + 10);
progressRing.percentage = percentage;
progressRing.textContent = `${percentage}%`;
const value = Math.min(100, progressRing.value + 10);
progressRing.value = value;
progressRing.textContent = `${value}%`;
});
subtractButton.addEventListener('click', () => {
const percentage = Math.max(0, progressRing.percentage - 10)
progressRing.percentage = percentage;
progressRing.textContent = `${percentage}%`;
const value = Math.max(0, progressRing.value - 10)
progressRing.value = value;
progressRing.textContent = `${value}%`;
});
</script>
```

View File

@@ -0,0 +1,84 @@
# QR Code
[component-header:sl-qr-code]
Generates a [QR code](https://www.qrcode.com/) and renders it using the [Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API).
QR codes are useful for providing small pieces of information to users who can quickly scan them with a smartphone. Most smartphones have built-in QR code scanners, so simply pointing the camera at a QR code will decode it and allow the user to visit a website, dial a phone number, read a message, etc.
```html preview
<div class="qr-overview">
<sl-qr-code value="https://shoelace.style/" label="Scan this code to visit Shoelace on the web!"></sl-qr-code>
<br>
<sl-input maxlength="255" clearable></sl-input>
</div>
<script>
const container = document.querySelector('.qr-overview');
const qrCode = container.querySelector('sl-qr-code');
const input = container.querySelector('sl-input');
input.value = qrCode.value;
input.addEventListener('sl-input', () => qrCode.value = input.value);
</script>
<style>
.qr-overview {
max-width: 256px;
}
.qr-overview sl-input {
margin-top: 1rem;
}
</style>
```
## Examples
### Colors
Use the `fill` and `background` attributes to modify the QR code's colors. You should always ensure good contrast for optimal compatibility with QR code scanners.
```html preview
<sl-qr-code value="https://shoelace.style/" fill="deeppink" background="white"></sl-qr-code>
```
### Size
Use the `size` attribute to change the size of the QR code.
```html preview
<sl-qr-code value="https://shoelace.style/" size="64"></sl-qr-code>
```
### Radius
Create a rounded effect with the `radius` attribute.
```html preview
<sl-qr-code value="https://shoelace.style/" radius="0.5"></sl-qr-code>
```
### Error Correction
QR codes can be rendered with various levels of [error correction](https://www.qrcode.com/en/about/error_correction.html) that can be set using the `error-correction` attribute. This example generates four codes with the same value using different error correction levels.
```html preview
<div class="qr-error-correction">
<sl-qr-code value="https://shoelace.style/" error-correction="L"></sl-qr-code>
<sl-qr-code value="https://shoelace.style/" error-correction="M"></sl-qr-code>
<sl-qr-code value="https://shoelace.style/" error-correction="Q"></sl-qr-code>
<sl-qr-code value="https://shoelace.style/" error-correction="H"></sl-qr-code>
</div>
<style>
.qr-error-correction {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
</style>
```
[component-metadata:sl-qr-code]

View File

@@ -0,0 +1,29 @@
# Radio Group
[component-header:sl-radio-group]
Radio Groups are used to group multiple radios so they function as a single control.
```html preview
<sl-radio-group label="Select an item">
<sl-radio value="1" checked>Item 1</sl-radio>
<sl-radio value="2">Item 2</sl-radio>
<sl-radio value="3">Item 3</sl-radio>
</sl-radio-group>
```
## Examples
### Showing the Fieldset
You can show a fieldset and legend that wraps the radio group using the `fieldset` attribute.
```html preview
<sl-radio-group label="Select an item" fieldset>
<sl-radio value="1" checked>Item 1</sl-radio>
<sl-radio value="2">Item 2</sl-radio>
<sl-radio value="3">Item 3</sl-radio>
</sl-radio-group>
```
[component-metadata:sl-radio-group]

View File

@@ -4,39 +4,31 @@
Radios allow the user to select one option from a group of many.
Radios are designed to be used with [radio groups](/components/radio-group). As such, all of the examples on this page utilize them to demonstrate their correct usage.
```html preview
<sl-radio>Radio</sl-radio>
<sl-radio-group label="Select an option" no-fieldset>
<sl-radio value="1" checked>Option 1</sl-radio>
<sl-radio value="2">Option 2</sl-radio>
<sl-radio value="3">Option 3</sl-radio>
</sl-radio-group>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
## Examples
### Checked
Use the `checked` attribute to activate the radio.
```html preview
<sl-radio checked>Checked</sl-radio>
```
### Disabled
Use the `disabled` attribute to disable the radio.
Use the `disabled` attribute to disable a radio.
```html preview
<sl-radio disabled>Disabled</sl-radio>
```
### Grouping Radios
Radios are grouped based on their `name` attribute and scoped to the nearest form.
```html preview
<sl-radio name="option" checked>Option 1</sl-radio><br>
<sl-radio name="option">Option 2</sl-radio><br>
<sl-radio name="option">Option 3</sl-radio><br>
<sl-radio name="option">Option 4</sl-radio>
<sl-radio-group label="Select an option" no-fieldset>
<sl-radio value="1" checked>Option 1</sl-radio>
<sl-radio value="2">Option 2</sl-radio>
<sl-radio value="3">Option 3</sl-radio>
<sl-radio value="4" disabled>Disabled</sl-radio>
</sl-radio-group>
```
[component-metadata:sl-radio]

View File

@@ -5,16 +5,16 @@
Ranges allow the user to select a single value within a given range using a slider.
```html preview
<sl-range min="0" max="100" step="1"></sl-range>
<sl-range></sl-range>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
## Examples
### Disabled
Use the `disabled` prop to disable a slider.
Use the `disabled` attribute to disable a slider.
```html preview
<sl-range min="0" max="100" step="1" disabled></sl-range>
@@ -36,9 +36,20 @@ To disable the tooltip, set `tooltip` to `none`.
<sl-range min="0" max="100" step="1" tooltip="none"></sl-range>
```
### Custom Track Colors
You can customize the active and inactive portions of the track using the `--track-color-active` and `--track-color-inactive` custom properties.
```html preview
<sl-range style="
--track-color-active: rgb(var(--sl-color-primary-600));
--track-color-inactive: rgb(var(--sl-color-primary-200));
"></sl-range>
```
### Custom Tooltip Formatter
You can change the tooltip's content by setting the `tooltipFormatter` prop to a function that accepts the range's value as an argument.
You can change the tooltip's content by setting the `tooltipFormatter` property to a function that accepts the range's value as an argument.
```html preview
<sl-range min="0" max="100" step="1" class="range-with-custom-formatter"></sl-range>
@@ -49,4 +60,25 @@ You can change the tooltip's content by setting the `tooltipFormatter` prop to a
</script>
```
### Labels
Use the `label` attribute to give the range an accessible label. For labels that contain HTML, use the `label` slot instead.
```html preview
<sl-range label="Volume" min="0" max="100"></sl-input>
```
### Help Text
Add descriptive help text to a range with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
```html preview
<sl-range
label="Volume"
help-text="Controls the volume of the current song."
min="0"
max="100"
></sl-input>
```
[component-metadata:sl-range]

79
docs/components/rating.md Normal file
View File

@@ -0,0 +1,79 @@
# Rating
[component-header:sl-rating]
Ratings give users a way to quickly view and provide feedback.
```html preview
<sl-rating></sl-rating>
```
## Examples
### Maximum Value
Ratings are 0-5 by default. To change the maximum possible value, use the `max` attribute.
```html preview
<sl-rating max="3"></sl-rating>
```
### Precision
Use the `precision` attribute to let users select fractional ratings.
```html preview
<sl-rating precision=".5" value="2.5"></sl-rating>
```
## Symbol Sizes
Set the `--symbol-size` custom property to adjust the size.
```html preview
<sl-rating style="--symbol-size: 2rem;"></sl-rating>
```
### Readonly
Use the `readonly` attribute to display a rating that users can't change.
```html preview
<sl-rating readonly value="3"></sl-rating>
```
### Disabled
Use the `disable` attribute to disable the rating.
```html preview
<sl-rating disabled value="3"></sl-rating>
```
### Custom Icons
```html preview
<sl-rating class="rating-hearts" style="--symbol-color-active: #ff4136;"></sl-rating>
<script>
const rating = document.querySelector('.rating-hearts');
rating.getSymbol = () => '<sl-icon name="heart-fill"></sl-icon>';
</script>
```
### Value-based Icons
```html preview
<sl-rating class="rating-emojis"></sl-rating>
<script>
const rating = document.querySelector('.rating-emojis');
rating.getSymbol = (value) => {
const icons = ['emoji-angry', 'emoji-frown', 'emoji-expressionless', 'emoji-smile', 'emoji-laughing'];
return `<sl-icon name="${icons[value - 1]}"></sl-icon>`;
};
</script>
```
[component-metadata:sl-rating]

View File

@@ -0,0 +1,61 @@
# Relative Time
[component-header:sl-relative-time]
Outputs a localized time phrase relative to the current date and time.
Localization is handled by the browser's [`Intl.RelativeTimeFormat` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat). No language packs are required.
```html preview
<!-- Shoelace 2 release date 🎉 -->
<sl-relative-time date="2020-07-15T09:17:00-04:00"></sl-relative-time>
```
The `date` attribute determines when the date/time is calculated from. It must be a string that [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) can interpret or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object set via JavaScript.
?> When using strings, avoid ambiguous dates such as `03/04/2020` which can be interpreted as March 4 or April 3 depending on the user's browser and locale. Instead, always use a valid [ISO 8601 date time string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#Date_Time_String_Format) to ensure the date will be parsed properly by all clients.
!> The `Intl.RelativeTimeFormat` API is available [in all major browsers](https://caniuse.com/mdn-javascript_builtins_intl_relativetimeformat), but it only became available to Safari in version 14. If you need to support Safari 13, you'll need to [use a polyfill](https://github.com/catamphetamine/relative-time-format).
## Examples
### Keeping Time in Sync
Use the `sync` attribute to update the displayed value automatically as time passes.
```html preview
<div class="relative-time-sync">
<sl-relative-time sync></sl-relative-time>
</div>
<script>
const container = document.querySelector('.relative-time-sync');
const relativeTime = container.querySelector('sl-relative-time');
relativeTime.date = new Date(new Date().getTime() - 60000);
</script>
```
### Formatting Styles
You can change how the time is displayed using the `format` attribute. Note that some locales may display the same values for `narrow` and `short` formats.
```html preview
<sl-relative-time date="2020-07-15T09:17:00-04:00" format="narrow"></sl-relative-time><br>
<sl-relative-time date="2020-07-15T09:17:00-04:00" format="short"></sl-relative-time><br>
<sl-relative-time date="2020-07-15T09:17:00-04:00" format="long"></sl-relative-time>
```
### Localization
Use the `locale` attribute to set the desired locale.
```html preview
English: <sl-relative-time date="2020-07-15T09:17:00-04:00" locale="en-US"></sl-relative-time><br>
Chinese: <sl-relative-time date="2020-07-15T09:17:00-04:00" locale="zh-CN"></sl-relative-time><br>
German: <sl-relative-time date="2020-07-15T09:17:00-04:00" locale="de"></sl-relative-time><br>
Greek: <sl-relative-time date="2020-07-15T09:17:00-04:00" locale="el"></sl-relative-time><br>
Russian: <sl-relative-time date="2020-07-15T09:17:00-04:00" locale="ru"></sl-relative-time>
```
[component-metadata:sl-relative-time]

View File

@@ -0,0 +1,39 @@
# Resize Observer
[component-header:sl-resize-observer]
The Resize Observer component offers a thin, declarative interface to the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
The resize observer will report changes to the dimensions of the elements it wraps through the `sl-resize` event. When emitted, a collection of [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry) objects will be attached to `event.detail` that contains the target element and information about its dimensions.
```html preview
<div class="resize-observer-overview">
<sl-resize-observer>
<div>
Resize this box and watch the console 👉
</div>
</sl-resize-observer>
</div>
<script>
const container = document.querySelector('.resize-observer-overview');
const resizeObserver = container.querySelector('sl-resize-observer');
resizeObserver.addEventListener('sl-resize', event => {
console.log(event.detail);
});
</script>
<style>
.resize-observer-overview div {
display: flex;
border: solid 2px rgb(var(--sl-input-border-color));
align-items: center;
justify-content: center;
text-align: center;
padding: 4rem 2rem;
}
</style>
```
[component-metadata:sl-resize-observer]

View File

@@ -0,0 +1,37 @@
# Responsive Media
[component-header:sl-responsive-media]
Displays media in the desired aspect ratio.
You can slot in any [replaced element](https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element), including `<iframe>`, `<img>`, and `<video>`. As the element's width changes, its height will resize proportionally. Only one element should be slotted into the container. The default aspect ratio is `16:9`.
```html preview
<sl-responsive-media>
<img src="https://images.unsplash.com/photo-1541427468627-a89a96e5ca1d?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1800&q=80" alt="A train riding through autumn foliage with mountains in the distance.">
</sl-responsive-media>
```
## Examples
### Responsive Images
The following image maintains a `4:3` aspect ratio as its container is resized.
```html preview
<sl-responsive-media aspect-ratio="4:3">
<img src="https://images.unsplash.com/photo-1473186578172-c141e6798cf4?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1800&q=80" alt="Two blue chairs on a sandy beach.">
</sl-responsive-media>
```
### Responsive Videos
The following video is embedded using an `iframe` and maintains a `16:9` aspect ratio as its container is resized.
```html preview
<sl-responsive-media aspect-ratio="16:9">
<iframe src="https://player.vimeo.com/video/1053647?title=0&byline=0&portrait=0" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
</sl-responsive-media>
```
[component-metadata:sl-responsive-media]

View File

@@ -5,64 +5,116 @@
Selects allow you to choose one or more items from a dropdown menu.
```html preview
<sl-select placeholder="Select one">
<sl-select>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item value="option-4">Option 4</sl-menu-item>
<sl-menu-item value="option-5">Option 5</sl-menu-item>
<sl-menu-item value="option-6">Option 6</sl-menu-item>
</sl-select>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
## Examples
### Labels
### Placeholders
Use the `label` attribute to give the select an accessible label.
Use the `placeholder` attribute to add a placeholder.
```html preview
<sl-select label="Select one">
<sl-select placeholder="Select one">
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
```
### Help Text
### Clearable
Add descriptive help text to an input with the `help-text` slot.
Use the `clearable` attribute to make the control clearable.
```html preview
<sl-select label="Experience">
<sl-menu-item value="option-1">Novice</sl-menu-item>
<sl-menu-item value="option-2">Intermediate</sl-menu-item>
<sl-menu-item value="option-3">Advanced</sl-menu-item>
<sl-select placeholder="Clearable" clearable>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
```
<div slot="help-text">Please tell us your skill level.</div>
### Filled Selects
Add the `filled` attribute to draw a filled select.
```html preview
<sl-select filled>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
```
### Pill
Use the `pill` attribute to give selects rounded edges.
```html preview
<sl-select pill>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
```
### Disabled
Use the `disabled` attribute to disable a select.
```html preview
<sl-select placeholder="Disabled" disabled>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
```
### Multiple
To allow multiple options to be selected, use the `multiple` attribute.
To allow multiple options to be selected, use the `multiple` attribute. It's a good practice to use `clearable` when this option is enabled. When using this option, `value` will be an array instead of a string.
```html preview
<sl-select placeholder="Select a few" multiple>
<sl-select placeholder="Select a few" multiple clearable>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-divider></sl-divider>
<sl-menu-item value="option-4">Option 4</sl-menu-item>
<sl-menu-item value="option-5">Option 5</sl-menu-item>
<sl-menu-item value="option-6">Option 6</sl-menu-item>
</sl-select>
```
### Size
### Grouping Options
Options can be grouped visually using menu labels and dividers.
```html preview
<sl-select placeholder="Select one">
<sl-menu-label>Group 1</sl-menu-label>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-label>Group 2</sl-menu-label>
<sl-menu-item value="option-4">Option 4</sl-menu-item>
<sl-menu-item value="option-5">Option 5</sl-menu-item>
<sl-menu-item value="option-6">Option 6</sl-menu-item>
</sl-select>
```
### Sizes
Use the `size` attribute to change a select's size.
@@ -90,69 +142,91 @@ Use the `size` attribute to change a select's size.
</sl-select>
```
### Pill
### Selecting Options Programmatically
Use the `pill` prop to give selects rounded edges.
The `value` property is bound to the current selection. As the selection changes, so will the value. To programmatically manage the selection, update the `value` property.
```html preview
<sl-select label="Select one" pill multiple>
<div class="selecting-example">
<sl-select placeholder="">
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
<br>
<sl-button data-option="option-1">Set 1</sl-button>
<sl-button data-option="option-2">Set 2</sl-button>
<sl-button data-option="option-3">Set 3</sl-button>
</div>
<script>
const container = document.querySelector('.selecting-example');
const select = container.querySelector('sl-select');
[...container.querySelectorAll('sl-button')].map(button => {
button.addEventListener('click', () => {
select.value = button.dataset.option;
});
});
</script>
```
### Labels
Use the `label` attribute to give the select an accessible label. For labels that contain HTML, use the `label` slot instead.
```html preview
<sl-select label="Select one">
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
```
### Groups
### Help Text
Options can be grouped visually using menu labels and menu dividers.
Add descriptive help text to a select with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
```html preview
<sl-select placeholder="Select one">
<sl-menu-label>Group 1</sl-menu-label>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<sl-menu-divider></sl-menu-divider>
<sl-menu-label>Group 2</sl-menu-label>
<sl-menu-item value="option-4">Option 4</sl-menu-item>
<sl-menu-item value="option-5">Option 5</sl-menu-item>
<sl-menu-item value="option-6">Option 6</sl-menu-item>
<sl-select
label="Experience"
help-text="Please tell us your skill level."
>
<sl-menu-item value="option-1">Novice</sl-menu-item>
<sl-menu-item value="option-2">Intermediate</sl-menu-item>
<sl-menu-item value="option-3">Advanced</sl-menu-item>
</sl-select>
```
### Disabled
### Prefix & Suffix Icons
Use the `disabled` prop to disable a select.
Use the `prefix` and `suffix` slots to add icons.
```html preview
<sl-select placeholder="Disabled" disabled>
<sl-select placeholder="Small" size="small">
<sl-icon name="house" slot="prefix"></sl-icon>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<sl-icon name="chat" slot="suffix"></sl-icon>
</sl-select>
```
### Validation
Show a valid or invalid state by setting the `valid` and `invalid` attributes, respectively. Help text can be used to provide feedback for validation and will be styled accordingly.
```html preview
<sl-select placeholder="Valid" valid>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<div slot="help-text">This is a valid selection!</div>
</sl-select>
<br>
<sl-select placeholder="Invalid" invalid>
<sl-select placeholder="Medium" size="medium">
<sl-icon name="house" slot="prefix"></sl-icon>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<div slot="help-text">This is not a valid selection!</div>
<sl-icon name="chat" slot="suffix"></sl-icon>
</sl-select>
<br>
<sl-select placeholder="Large" size="large">
<sl-icon name="house" slot="prefix"></sl-icon>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
<sl-icon name="chat" slot="suffix"></sl-icon>
</sl-select>
```

204
docs/components/skeleton.md Normal file
View File

@@ -0,0 +1,204 @@
# Skeleton
[component-header:sl-skeleton]
Skeletons are used to show where content will eventually be drawn.
These are simple containers for scaffolding layouts that mimic what users will see when content has finished loading. This prevents large areas of empty space during asynchronous operations.
Skeletons try not to be opinionated, as there are endless possibilities for designing layouts. Therefore, you'll likely use more than one skeleton to create the effect you want. If you find yourself using them frequently, consider creating a template that renders them with the desired arrangement and styles.
```html preview
<div class="skeleton-overview">
<header>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
</header>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
</div>
<style>
.skeleton-overview header {
display: flex;
align-items: center;
margin-bottom: 1rem;
}
.skeleton-overview header sl-skeleton:last-child {
flex: 0 0 auto;
width: 30%;
}
.skeleton-overview sl-skeleton {
margin-bottom: 1rem;
}
.skeleton-overview sl-skeleton:nth-child(1) {
float: left;
width: 3rem;
height: 3rem;
margin-right: 1rem;
vertical-align: middle;
}
.skeleton-overview sl-skeleton:nth-child(3) {
width: 95%;
}
.skeleton-overview sl-skeleton:nth-child(4) {
width: 80%;
}
</style>
```
## Examples
### Effects
There are two built-in effects, `sheen` and `pulse`. Effects are intentionally subtle, as they can be distracting when used extensively. The default is `none`, which displays a static, non-animated skeleton.
```html preview
<div class="skeleton-effects">
<sl-skeleton effect="none"></sl-skeleton>
None
<sl-skeleton effect="sheen"></sl-skeleton>
Sheen
<sl-skeleton effect="pulse"></sl-skeleton>
Pulse
</div>
<style>
.skeleton-effects {
font-size: var(--sl-font-size-small);
}
.skeleton-effects sl-skeleton:not(:first-child) {
margin-top: 1rem;
}
</style>
```
### Paragraphs
Use multiple skeletons and some clever styles to simulate paragraphs.
```html preview
<div class="skeleton-paragraphs">
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
</div>
<style>
.skeleton-paragraphs sl-skeleton {
margin-bottom: 1rem;
}
.skeleton-paragraphs sl-skeleton:nth-child(2) {
width: 95%;
}
.skeleton-paragraphs sl-skeleton:nth-child(4) {
width: 90%;
}
.skeleton-paragraphs sl-skeleton:last-child {
width: 50%;
}
</style>
```
### Avatars
Set a matching width and height to make a circle, square, or rounded avatar skeleton.
```html preview
<div class="skeleton-avatars">
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
<sl-skeleton></sl-skeleton>
</div>
<style>
.skeleton-avatars sl-skeleton {
display: inline-block;
width: 3rem;
height: 3rem;
margin-right: .5rem;
}
.skeleton-avatars sl-skeleton:nth-child(1) {
--border-radius: 0;
}
.skeleton-avatars sl-skeleton:nth-child(2) {
--border-radius: var(--sl-border-radius-medium);
}
</style>
```
### Custom Shapes
Use the `--border-radius` custom property to make circles, squares, and rectangles. For more complex shapes, you can apply `clip-path` to the `indicator` part. [Try Clippy](https://bennettfeely.com/clippy/) if you need help generating custom shapes.
```html preview
<div class="skeleton-shapes">
<sl-skeleton class="square"></sl-skeleton>
<sl-skeleton class="circle"></sl-skeleton>
<sl-skeleton class="triangle"></sl-skeleton>
<sl-skeleton class="cross"></sl-skeleton>
<sl-skeleton class="comment"></sl-skeleton>
</div>
<style>
.skeleton-shapes sl-skeleton {
display: inline-flex;
width: 50px;
height: 50px;
}
.skeleton-shapes .square::part(indicator) {
--border-radius: var(--sl-border-radius-medium);
}
.skeleton-shapes .circle::part(indicator) {
--border-radius: var(--sl-border-radius-circle);
}
.skeleton-shapes .triangle::part(indicator) {
--border-radius: 0;
clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
.skeleton-shapes .cross::part(indicator) {
--border-radius: 0;
clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
}
.skeleton-shapes .comment::part(indicator) {
--border-radius: 0;
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
}
.skeleton-shapes sl-skeleton:not(:last-child) {
margin-right: .5rem;
}
</style>
```
### Custom Colors
Set the `--color` and `--sheen-color` custom properties to adjust the skeleton's color.
```html preview
<sl-skeleton effect="sheen" style="--color: tomato; --sheen-color: #ffb094;"></sl-skeleton>
```
[component-metadata:sl-skeleton]

View File

@@ -12,7 +12,7 @@ Spinners are used to show the progress of an indeterminate operation.
### Size
Spinners are sized relative to the current font size. To change their size, set the `font-size` property on the spinner itself or on a parent element as shown below.
Spinners are sized based on the current font size. To change their size, set the `font-size` property on the spinner itself or on a parent element as shown below.
```html preview
<sl-spinner></sl-spinner>
@@ -20,20 +20,20 @@ Spinners are sized relative to the current font size. To change their size, set
<sl-spinner style="font-size: 3rem;"></sl-spinner>
```
### Stroke Width
### Track Width
The width of the spinner can be changed by setting the `--stroke-width` custom property.
The width of the spinner's track can be changed by setting the `--track-width` custom property.
```html preview
<sl-spinner style="font-size: 2rem; --stroke-width: 6px;"></sl-spinner>
<sl-spinner style="font-size: 3rem; --track-width: 6px;"></sl-spinner>
```
### Color
The spinner's color can be changed by setting the `--color` custom property.
The spinner's colors can be changed by setting the `--indicator-color` and `--track-color` custom properties.
```html preview
<sl-spinner style="font-size: 2rem; --color: tomato;"></sl-spinner>
<sl-spinner style="font-size: 3rem; --indicator-color: deeppink; --track-color: pink;"></sl-spinner>
```
[component-metadata:sl-spinner]

View File

@@ -8,7 +8,7 @@ Switches allow the user to toggle an option on or off.
<sl-switch>Switch</sl-switch>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
## Examples
@@ -28,5 +28,12 @@ Use the `disabled` attribute to disable the switch.
<sl-switch disabled>Disabled</sl-switch>
```
### Custom Size
Use the available custom properties to make the switch a different size.
```html preview
<sl-switch style="--width: 80px; --height: 32px; --thumb-size: 26px;"></sl-switch>
```
[component-metadata:sl-switch]

View File

@@ -4,7 +4,7 @@
Tab groups organize content into a container that shows one section at a time.
Tab groups make use of [tabs](/components/tab.md) and [tab panels](/components/tab-panel.md). Each tab must be slotted into the `nav` slot and its `panel` must refer to a tab panel of the same name.
Tab groups make use of [tabs](/components/tab) and [tab panels](/components/tab-panel). Each tab must be slotted into the `nav` slot and its `panel` must refer to a tab panel of the same name.
```html preview
<sl-tab-group>
@@ -40,12 +40,12 @@ Tabs can be shown on the bottom by setting `placement` to `bottom`.
</sl-tab-group>
```
### Tabs on Left
### Tabs on Start
Tabs can be shown on the left by setting `placement` to `left`.
Tabs can be shown on the starting side by setting `placement` to `start`.
```html preview
<sl-tab-group placement="left">
<sl-tab-group placement="start">
<sl-tab slot="nav" panel="general">General</sl-tab>
<sl-tab slot="nav" panel="custom">Custom</sl-tab>
<sl-tab slot="nav" panel="advanced">Advanced</sl-tab>
@@ -58,12 +58,12 @@ Tabs can be shown on the left by setting `placement` to `left`.
</sl-tab-group>
```
### Tabs on Right
### Tabs on End
Tabs can be shown on the right by setting `placement` to `right`.
Tabs can be shown on the ending side by setting `placement` to `end`.
```html preview
<sl-tab-group placement="right">
<sl-tab-group placement="end">
<sl-tab slot="nav" panel="general">General</sl-tab>
<sl-tab slot="nav" panel="custom">Custom</sl-tab>
<sl-tab slot="nav" panel="advanced">Advanced</sl-tab>
@@ -76,6 +76,42 @@ Tabs can be shown on the right by setting `placement` to `right`.
</sl-tab-group>
```
### Closable Tabs
Add the `closable` attribute to a tab to show a close button. This example shows how you can dynamically remove tabs from the DOM when the close button is activated.
```html preview
<sl-tab-group class="tabs-closable">
<sl-tab slot="nav" panel="general">General</sl-tab>
<sl-tab slot="nav" panel="closable-1" closable>Closable 1</sl-tab>
<sl-tab slot="nav" panel="closable-2" closable>Closable 2</sl-tab>
<sl-tab slot="nav" panel="closable-3" closable>Closable 3</sl-tab>
<sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
<sl-tab-panel name="closable-1">This is the first closable tab panel.</sl-tab-panel>
<sl-tab-panel name="closable-2">This is the second closable tab panel.</sl-tab-panel>
<sl-tab-panel name="closable-3">This is the third closable tab panel.</sl-tab-panel>
</sl-tab-group>
<script>
const tabGroup = document.querySelector('.tabs-closable');
tabGroup.addEventListener('sl-close', async event => {
const tab = event.target;
const panel = tabGroup.querySelector(`sl-tab-panel[name="${tab.panel}"]`);
// Show the previous tab if the tab is currently active
if (tab.active) {
tabGroup.show(tab.previousElementSibling.panel);
}
// Remove the tab + panel
tab.remove();
panel.remove();
});
</script>
```
### Scrolling Tabs
When there are more tabs than horizontal space allows, the nav will be scrollable.
@@ -126,4 +162,22 @@ When there are more tabs than horizontal space allows, the nav will be scrollabl
</sl-tab-group>
```
### Manual Activation
When focused, keyboard users can press <kbd>Left</kbd> or <kbd>Right</kbd> to select the desired tab. By default, the corresponding tab panel will be shown immediately (automatic activation). You can change this behavior by setting `activation="manual"` which will require the user to press <kbd>Space</kbd> or <kbd>Enter</kbd> before showing the tab panel (manual activation).
```html preview
<sl-tab-group activation="manual">
<sl-tab slot="nav" panel="general">General</sl-tab>
<sl-tab slot="nav" panel="custom">Custom</sl-tab>
<sl-tab slot="nav" panel="advanced">Advanced</sl-tab>
<sl-tab slot="nav" panel="disabled" disabled>Disabled</sl-tab>
<sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
<sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
<sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
<sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
```
[component-metadata:sl-tab-group]

View File

@@ -2,7 +2,7 @@
[component-header:sl-tab-panel]
Tab panels are used inside tab groups to display content.
Tab panels are used inside [tab groups](/components/tab-group) to display tabbed content.
```html preview
<sl-tab-group>
@@ -18,6 +18,6 @@ Tab panels are used inside tab groups to display content.
</sl-tab-group>
```
?> Additional demonstrations can be found in the [tab group examples](/components/tab-group.md).
?> Additional demonstrations can be found in the [tab group examples](/components/tab-group).
[component-metadata:sl-tab-panel]

View File

@@ -2,14 +2,15 @@
[component-header:sl-tab]
Tabs are used inside tab groups to represent tab panels.
Tabs are used inside [tab groups](/components/tab-group) to represent and activate [tab panels](/components/tab-panel).
```html preview
<sl-tab>Tab</sl-tab>
<sl-tab active>Active</sl-tab>
<sl-tab closable>Closable</sl-tab>
<sl-tab disabled>Disabled</sl-tab>
```
?> Additional demonstrations can be found in the [tab group examples](/components/tab-group.md).
?> Additional demonstrations can be found in the [tab group examples](/components/tab-group).
[component-metadata:sl-tab]

View File

@@ -7,16 +7,16 @@ Tags are used as labels to organize things or to indicate a selection.
```html preview
<sl-tag type="primary">Primary</sl-tag>
<sl-tag type="success">Success</sl-tag>
<sl-tag type="info">Info</sl-tag>
<sl-tag type="neutral">Neutral</sl-tag>
<sl-tag type="warning">Warning</sl-tag>
<sl-tag type="danger">Danger</sl-tag>
```
## Examples
### Size
### Sizes
Use the `size` prop to change a tab's size.
Use the `size` attribute to change a tab's size.
```html preview
<sl-tag size="small">Small</sl-tag>
@@ -26,7 +26,7 @@ Use the `size` prop to change a tab's size.
### Pill
Use the `pill` prop to give tabs rounded edges.
Use the `pill` attribute to give tabs rounded edges.
```html preview
<sl-tag size="small" pill>Small</sl-tag>
@@ -34,14 +34,32 @@ Use the `pill` prop to give tabs rounded edges.
<sl-tag size="large" pill>Large</sl-tag>
```
### Clearable
### Removable
Use the `clearable` attribute to add a clear button to the tag.
Use the `removable` attribute to add a remove button to the tag.
```html preview
<sl-tag size="small" clearable>Small</sl-tag>
<sl-tag size="medium" clearable>Medium</sl-tag>
<sl-tag size="large" clearable>Large</sl-tag>
<div class="tags-removable">
<sl-tag size="small" removable>Small</sl-tag>
<sl-tag size="medium" removable>Medium</sl-tag>
<sl-tag size="large" removable>Large</sl-tag>
</div>
<script>
const div = document.querySelector('.tags-removable');
div.addEventListener('sl-remove', event => {
const tag = event.target;
tag.style.opacity = '0';
setTimeout(() => tag.style.opacity = '1', 2000);
});
</script>
<style>
.tags-removable sl-tag {
transition: var(--sl-transition-medium) opacity;
}
</style>
```
[component-metadata:sl-tag]

View File

@@ -8,28 +8,12 @@ Textareas collect data from the user and allow multiple lines of text.
<sl-textarea></sl-textarea>
```
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form.md) instead.
?> This component doesn't work with standard forms. Use [`<sl-form>`](/components/form) instead.
?> Please refer to the section on [form control validation](/components/form?id=form-control-validation) to learn how to do client-side validation.
## Examples
### Labels
Use the `label` attribute to give the textarea an accessible label.
```html preview
<sl-textarea label="Comments"></sl-textarea>
```
### Help Text
Add descriptive help text to a textarea with the `help-text` slot.
```html preview
<sl-textarea label="Feedback">
<div slot="help-text">Please tell us what you think.</div>
</sl-textarea>
```
### Rows
Use the `rows` attribute to change the number of text rows that get shown.
@@ -46,27 +30,51 @@ Use the `placeholder` attribute to add a placeholder.
<sl-textarea placeholder="Type something"></sl-textarea>
```
### Filled Textareas
Add the `filled` attribute to draw a filled textarea.
```html preview
<sl-textarea placeholder="Type something" filled></sl-textarea>
```
### Disabled
Use the `disabled` attribute to disable an input.
Use the `disabled` attribute to disable a textarea.
```html preview
<sl-textarea placeholder="Textarea" disabled></sl-textarea>
```
### Validation
### Sizes
Show a valid or invalid state by setting the `valid` and `invalid` attributes, respectively. Help text can be used to provide feedback for validation and will be styled accordingly.
Use the `size` attribute to change a textarea's size.
```html preview
<sl-textarea label="Valid" valid>
<div slot="help-text">This is a valid textarea.</div>
</sl-textarea>
<sl-textarea placeholder="Small" size="small"></sl-textarea>
<br>
<sl-textarea placeholder="Medium" size="medium"></sl-textarea>
<br>
<sl-textarea placeholder="Large" size="large"></sl-textarea>
```
<sl-textarea label="Invalid" invalid>
<div slot="help-text">This is an invalid textarea.</div>
### Labels
Use the `label` attribute to give the textarea an accessible label. For labels that contain HTML, use the `label` slot instead.
```html preview
<sl-textarea label="Comments"></sl-textarea>
```
### Help Text
Add descriptive help text to a textarea with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
```html preview
<sl-textarea
label="Feedback"
help-text="Please tell us what you think."
>
</sl-textarea>
```

View File

@@ -86,7 +86,7 @@ Use the `placement` attribute to set the preferred placement of the tooltip.
width: 250px;
}
.tooltip-placement-example-row::after {
.tooltip-placement-example-row:after {
content: '';
display: table;
clear: both;
@@ -94,6 +94,7 @@ Use the `placement` attribute to set the preferred placement of the tooltip.
.tooltip-placement-example sl-button {
float: left;
width: 2.5rem;
margin-right: 0.25rem;
margin-bottom: 0.25rem;
}
@@ -121,7 +122,7 @@ Set the `trigger` attribute to `click` to toggle the tooltip on click instead of
### Manual Trigger
Tooltips can be controller programmatically by setting the `trigger` attribute to `manual`. Use the `open` prop to control when the tooltip is shown.
Tooltips can be controller programmatically by setting the `trigger` attribute to `manual`. Use the `open` attribute to control when the tooltip is shown.
```html preview
<sl-button style="margin-right: 4rem;">Toggle Manually</sl-button>
@@ -154,7 +155,7 @@ You can control the size of tooltip arrows by overriding the `--sl-tooltip-arrow
</div>
```
To override it globally, set it in a root block in your stylesheet after `shoelace.css` is loaded.
To override it globally, set it in a root block in your stylesheet after the Shoelace stylesheet is loaded.
```css
:root {
@@ -162,5 +163,40 @@ To override it globally, set it in a root block in your stylesheet after `shoela
}
```
### HTML in Tooltips
Use the `content` slot to create tooltips with HTML content. Tooltips are designed only for text and presentational elements. Avoid placing interactive content, such as buttons, links, and form controls, in a tooltip.
```html preview
<sl-tooltip>
<div slot="content">I'm not <strong>just</strong> a tooltip, I'm a <em>tooltip</em> with HTML!</div>
<sl-button>Hover me</sl-button>
</sl-tooltip>
```
### Hoisting
Tooltips will be clipped if they're inside a container that has `overflow: auto|hidden|scroll`. The `hoist` attribute forces the tooltip to use a fixed positioning strategy, allowing it to break out of the container. In this case, the tooltip will be positioned relative to its containing block, which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
```html preview
<div class="tooltip-hoist">
<sl-tooltip content="This is a tooltip">
<sl-button>No Hoist</sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" hoist>
<sl-button>Hoist</sl-button>
</sl-tooltip>
</div>
<style>
.tooltip-hoist {
border: solid 2px rgb(var(--sl-panel-border-color));
overflow: hidden;
padding: var(--sl-spacing-medium);
position: relative;
}
</style>
```
[component-metadata:sl-tooltip]

View File

@@ -6,23 +6,30 @@ Shoelace components can be customized at a high level through design tokens. Thi
Shoelace makes use of several design tokens to provide a consistent appearance across components. You can customize them and use them in your own application with pure CSS — no preprocessor required.
Design tokens offer a high-level way to customize the library with minimal effort. There are no component-specific variables, however, as design tokens are intended to be generic and highly reusable. To customize an individual component, refer to the section entitled [Component parts](#component-parts).
Design tokens offer a high-level way to customize the library with minimal effort. There are no component-specific variables, however, as design tokens are intended to be generic and highly reusable. To customize an individual component, refer to the section entitled [Component Parts](#component-parts).
Design tokens are CSS custom properties ("CSS variables") that are defined in the `:root` block of `shoelace.css`. This stylesheet is imported when you install Shoelace, so design tokens are available on your page at that point. Because design tokens are global, they're always prefixed with `--sl` to avoid collisions with other libraries.
Design tokens are accessed through CSS custom properties that are defined in your theme. Because design tokens live at the page level, they're prefixed with `--sl-` to avoid collisions with other libraries.
To customize a design token, simply override it in your stylesheet using a `:root` block.
To customize a design token, simply override it in your stylesheet using a `:root` block. Here's an example that changes the primary theme to purple based on existing [color primitives](/tokens/color#primitives).
```css
:root {
/* Changes the primary color to a shade of orange at 90% saturation */
--sl-color-primary-hue: 30;
--sl-color-primary-saturation: 90%;
/* Changes the primary theme color to purple using primitives */
--sl-color-primary-50: var(--sl-color-purple-50);
--sl-color-primary-100: var(--sl-color-purple-100);
--sl-color-primary-200: var(--sl-color-purple-200);
--sl-color-primary-300: var(--sl-color-purple-300);
--sl-color-primary-400: var(--sl-color-purple-400);
--sl-color-primary-500: var(--sl-color-purple-500);
--sl-color-primary-600: var(--sl-color-purple-600);
--sl-color-primary-700: var(--sl-color-purple-700);
--sl-color-primary-800: var(--sl-color-purple-800);
--sl-color-primary-900: var(--sl-color-purple-900);
--sl-color-primary-950: var(--sl-color-purple-950);
}
```
Design tokens are described further along in this documentation. For a complete list, refer to `shoelace.scss` in the project's [source code](https://github.com/shoelace-style/shoelace/blob/master/src/styles/shoelace.scss).
!> **Never modify variables directly in `shoelace.css`** because your changes will be overwritten when you upgrade the library. Even if you don't plan on upgrading, it's always better to override design tokens in your own stylesheet for better maintainability.
Many design tokens are described further along in this documentation. For a complete list, refer to `src/themes/light.styles.ts` in the project's [source code](https://github.com/shoelace-style/shoelace/blob/current/src/themes/light.styles.ts).
## Component Parts
@@ -39,7 +46,7 @@ Here's an example that modifies buttons with the `tomato-button` class.
<style>
.tomato-button::part(base) {
background: white;
background: rgb(var(--sl-color-neutral-0));
border: solid 1px tomato;
}
@@ -71,7 +78,7 @@ At first glance, this approach might seem a bit verbose or even limiting, but it
Most (but not all) components expose parts. You can find them in each component's API documention under the "CSS Parts" section.
### Custom Properties
## Custom Properties
For convenience, some components expose CSS custom properties you can override. These are not design tokens, nor do they have the same `--sl-` prefix since they're scoped to a component.
@@ -99,25 +106,50 @@ Alternatively, you can set them inline directly on the element.
Not all components expose CSS custom properties. For those that do, they can be found in the component's API documentation.
## Writing a Theme
## Animations
Customizing Shoelace is fairly easy, but you can take things a step further and create a full-blown theme if you want. A theme is nothing more than a stylesheet that uses the APIs described above to customize Shoelace's design tokens and components.
Some components use animation, such as when a dialog is shown or hidden. Animations are performed using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) rather than CSS. However, you can still customize them through Shoelace's animation registry. If a component has customizable animations, they'll be listed in the "Animation" section of its documentation.
It's a good practice to include `shoelace.css` in your app and add your theme's stylesheet directly below it. That way, when an update introduces a new design token, your theme will still work with the default design token value.
To customize a default animation, use the `setDefaultAnimation()` method. The function accepts an animation name (found in the component's docs) and an object with `keyframes` and `options` or `null` to disable the animation.
### Submitting a Theme
This example will make all dialogs use a custom show animation.
**I am very interested in offering well-designed themes to complement this library.** To submit a theme for review, please open an issue on GitHub with the theme attached. Once approved, your theme will be showcased in the project's documentation (that section is coming soon).
```js
import { setDefaultAnimation } from '@shoelace-style/shoelace/dist/utilities/animation-registry.js';
Themes that are in high demand include:
// Change the default animation for all dialogs
setDefaultAnimation('dialog.show', {
keyframes: [
{ transform: 'rotate(-10deg) scale(0.5)', opacity: '0' },
{ transform: 'rotate(0deg) scale(1)', opacity: '1' }
],
options: {
duration: 500
}
});
```
- Dark mode ([details](https://github.com/shoelace-style/shoelace/issues/98))
- High contrast ([details](https://github.com/shoelace-style/shoelace/issues/99))
If you only want to target a single component, use the `setAnimation()` method instead. This function accepts an element, an animation name, and an object comprised of animation `keyframes` and `options`.
**I am willing to contribute a minimum of $200 USD to commission each of the themes listed above.**
In this example, only the target dialog will use a custom show animation.
Please note the following requirements before submitting a theme.
```js
import { setAnimation } from '@shoelace-style/shoelace/dist/utilities/animation-registry.js';
- Themes must be complete and of high quality
- Themes must be available under the same open source license as Shoelace
- If a theme is not original, the derivative work must have a license that is compatible with Shoelace's license
// Change the animation for a single dialog
const dialog = document.querySelector('#my-dialog');
setAnimation(dialog, 'dialog.show', {
keyframes: [
{ transform: 'rotate(-10deg) scale(0.5)', opacity: '0' },
{ transform: 'rotate(0deg) scale(1)', opacity: '1' }
],
options: {
duration: 500
}
});
```
To learn more about creating Web Animations, refer to the documentation for [`Element.animate()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animate).
?> Animations respect the users `prefers-reduced-motion` setting. When this setting is enabled, animations will not be played. To disable animations for all users, pass in `null` instead of a keyframes/options object.

View File

@@ -1,35 +1,133 @@
# Installation
You can use Shoelace via CDN or by installing it locally.
You can use Shoelace via CDN or by installing it locally. You can also [cherry pick](#cherry-picking) individual components for faster load times.
## CDN Installation (Recommended)
The easiest way to install Shoelace is with the CDN. A lightweight loader will be added to your page that registers components asynchronously as you use them. It's like magic. ✨
Just add the following tags to your page.
The easiest way to install Shoelace is with the CDN. Just add the following tags to your page to get all components and the default light theme.
```html
<link rel="stylesheet" href="https://unpkg.com/@shoelace-style/shoelace@%VERSION%/dist/shoelace/shoelace.css">
<script type="module" src="https://unpkg.com/@shoelace-style/shoelace@%VERSION%/dist/shoelace/shoelace.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace.js"></script>
```
Now you can [start using Shoelace components!](/getting-started/usage.md)
### Dark Theme
If you prefer to use the dark theme instead, use this. Note the `sl-theme-dark` class on the `<html>` element. [Learn more about the Dark Theme.](/getting-started/themes#dark-theme)
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/dark.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace.js"></script>
```
### Light & Dark Theme
If you want to load the light or dark theme based on the user's `prefers-color-scheme` setting, use this. The `media` attributes ensure that only the user's preferred theme stylesheet loads and the `onload` attribute sets the appropriate [theme class](/getting-started/themes) on the `<html>` element.
```html
<link rel="stylesheet" media="(prefers-color-scheme:light)" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css">
<link rel="stylesheet" media="(prefers-color-scheme:dark)"
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/dark.css"
onload="document.documentElement.classList.add('sl-theme-dark');">
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace.js"></script>
```
Now you can [start using Shoelace!](/getting-started/usage)
## Local Installation
If you don't want to use the CDN, you can install Shoelace locally with the following command.
If you don't want to use the CDN, you can install Shoelace locally with the following command.
```sh
```bash
npm install @shoelace-style/shoelace
```
It's up to you to make the source files available to your app. One way to do this is to create a route in your app called `/assets/shoelace` that serves static files from `node_modules/@shoelace-style/shoelace`.
It's up to you to make the source files available to your app. One way to do this is to create a route in your app called `/shoelace` that serves static files from `node_modules/@shoelace-style/shoelace`.
Once you've done that, add the following tags to your page. Make sure to update `href` and `src` so they point to the route you created.
```html
<link rel="stylesheet" href="/assets/shoelace/shoelace.css">
<script type="module" src="/assets/shoelace/shoelace.esm.js"></script>
<link rel="stylesheet" href="/shoelace/dist/themes/light.css">
<script type="module" src="/shoelace/dist/shoelace.js"></script>
```
Now you can [start using Shoelace components!](/getting-started/usage.md)
Alternatively, [you can use a bundler](#bundling).
?> For clarity, the docs will usually show imports from `@shoelace-style/shoelace`. If you're not using a module resolver or bundler, you'll need to adjust these paths to point to the folder Shoelace is in.
## Setting the Base Path
Some components rely on assets (icons, images, etc.) and Shoelace needs to know where they're located. For convenience, Shoelace will try to auto-detect the correct location based on the script you've loaded it from. This assumes assets are colocated with `shoelace.js` and will "just work" for most users.
However, if you're [cherry picking](#cherry-picking) or [bundling](#bundling) Shoelace, you'll need to set the base path. You can do this one of two ways.
```html
<!-- Option 1: the data-shoelace attribute -->
<script src="bundle.js" data-shoelace="/path/to/shoelace"></script>
<!-- Option 2: the setBasePath() method -->
<script src="bundle.js"></script>
<script type="module">
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
setBasePath('/path/to/shoelace');
</script>
```
?> The library also exports a `getBasePath()` method you can use to reference assets.
## Cherry Picking
The previous approach is the _easiest_ way to load Shoelace, but easy isn't always efficient. You'll incur the full size of the library even if you only use a handful of components. This is convenient for prototyping, but may result in longer load times in production. To improve this, you can cherry pick the components you need.
Cherry picking can be done from your local install or [directly from the CDN](https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/). This will limit the number of files the browser has to download and reduce the amount of bytes being transferred. The disadvantage is that you need to load component manually.
Here's an example that loads only the button component. Again, if you're not using a module resolver, you'll need to adjust the path to point to the folder Shoelace is in.
```html
<link rel="stylesheet" href="@shoelace-style/shoelace/dist/themes/light.css">
<script type="module" data-shoelace="/path/to/shoelace">
import '@shoelace-style/shoelace/dist/components/button/button.js';
// <sl-button> is ready to use!
</script>
```
You can copy and paste the code to import a component from the "Importing" section of the component's documentation. Note that some components have dependencies that are automatically imported when you cherry pick. If a component has dependencies, they will be listed in the "Dependencies" section of its docs.
!> Never cherry pick components or utilities from `shoelace.js` as this will cause the browser to load the entire library. Instead, cherry pick from specific modules as shown above.
!> You will see files named `chunk.[hash].js` in the `chunks` directory. Never import these files directly, as they are generated and change from version to version.
## Bundling
Shoelace is distributed as a collection of standard ES modules that [all modern browsers can understand](https://caniuse.com/es6-module). However, importing a lot of modules can result in a lot of HTTP requests and potentially longer load times. Using a CDN can alleviate this, but some users may wish to further optimize their imports with a bundler.
To use Shoelace with a bundler, first install Shoelace along with your bundler of choice.
```bash
npm install @shoelace-style/shoelace
```
Now it's time to configure your bundler. Configurations vary for each tool, but here are some examples to help you get started.
- [Example webpack config](https://github.com/shoelace-style/webpack-example/blob/master/webpack.config.js)
- [Example Rollup config](https://github.com/shoelace-style/rollup-example/blob/master/rollup.config.js)
Once your bundler is configured, you'll be able to import Shoelace components and utilities.
```js
import '@shoelace-style/shoelace/dist/themes/light.css';
import '@shoelace-style/shoelace/dist/components/button/button.js';
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
import '@shoelace-style/shoelace/dist/components/input/input.js';
import '@shoelace-style/shoelace/dist/components/rating/rating.js';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
// Set the base path to the folder you copied Shoelace's assets to
setBasePath('/dist/shoelace');
// <sl-button>, <sl-icon>, <sl-input>, and <sl-rating> are ready to use!
```
!> Component modules include side effects for registration purposes. Because of this, importing directly from `@shoelace-style/shoelace` may result in a larger bundle size than necessary. For optimal tree shaking, always cherry pick, i.e. import components and utilities from their respective files, as shown above.

View File

@@ -1,27 +1,38 @@
<div class="splash">
<div class="splash-start">
<img class="splash-logo" src="/assets/images/wordmark.svg" alt="Shoelace" data-no-zoom >
<p><strong>A forward-thinking library of web components.</strong></p>
<ul>
<li>Works with all frameworks 🧩</li>
<li>Works with CDNs 🚛</li>
<li>Fully customizable with CSS 🎨</li>
<li>Open source 😸</li>
</ul>
<p>Designed in New Hampshire by <a href="https://twitter.com/claviska" rel="noopener" target="_blank">Cory LaViska</a>.</p>
</div>
<div class="splash-end">
<img class="splash-image" src="/assets/images/undraw-content-team.svg" alt="Cartoon of people assembling components while standing on a giant laptop." data-no-zoom />
</div>
<div class="splash-start">
<img class="splash-logo" src="/assets/images/wordmark.svg" alt="Shoelace">
# <span hidden>Shoelace:</span> A forward-thinking library of web components.
- Works with all frameworks 🧩
- Works with CDNs 🚛
- Fully customizable with CSS 🎨
- Includes a dark theme 🌛
- Built with accessibility in mind ♿️
- First-party [React wrappers](/getting-started/usage#react)
- Open source 😸
Designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska).
</div>
<div class="splash-end">
<img class="splash-image" src="/assets/images/undraw-content-team.svg" alt="Cartoon of people assembling components while standing on a giant laptop.">
</div>
</div>
[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/@shoelace-style/shoelace/badge)](https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace)
[![npm](https://img.shields.io/npm/dw/@shoelace-style/shoelace?label=npm&style=flat-square)](https://www.npmjs.com/package/@shoelace-style/shoelace)
[![License](https://img.shields.io/badge/license-MIT-232323.svg?style=flat-square)](https://github.com/shoelace-style/shoelace/blob/next/LICENSE.md)<br>
[![Discord](https://img.shields.io/badge/Discord-Join%20the%20chat-5965f2.svg?style=flat-square&logo=discord&logoColor=white)](https://discord.gg/mg8f26C)
[![Twitter](https://img.shields.io/badge/Twitter-Follow-00acee.svg?style=flat-square&logo=twitter&logoColor=white)](https://twitter.com/shoelace_style)
[![Sponsor](https://img.shields.io/badge/GitHub-Code-232323.svg?style=flat-square&logo=github&logoColor=white)](https://github.com/shoelace-style/shoelace)
## Quick Start
Add the following code to your page.
```html
<link rel="stylesheet" href="https://unpkg.com/@shoelace-style/shoelace@%VERSION%/dist/shoelace/shoelace.css">
<script type="module" src="https://unpkg.com/@shoelace-style/shoelace@%VERSION%/dist/shoelace/shoelace.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace.js"></script>
```
Now you have access to all of Shoelace's components! Try adding a button:
@@ -30,7 +41,7 @@ Now you have access to all of Shoelace's components! Try adding a button:
<sl-button>Click me</sl-button>
```
See the [installation instructions](getting-started/installation.md) for more details and other ways to install Shoelace.
See the [installation instructions](getting-started/installation) for more details and other ways to install Shoelace.
## New to Web Components?
@@ -42,7 +53,7 @@ Unfortunately, _framework-specific_ components fail us in a number of ways:
- You can only use them in the framework they're designed for 🔒
- Their lifespan is limited to that of the framework's ⏳
- New framework versions can lead to breaking changes, requiring substantial effort to update components 😭
- New frameworks/versions can lead to breaking changes, requiring substantial effort to update components 😭
Web components solve these problems. They're [supported by all modern browsers](https://caniuse.com/#feat=custom-elementsv1), they're framework-agnostic, and they're [part of the standard](https://developer.mozilla.org/en-US/docs/Web/Web_Components), so we know they'll be supported for many years to come.
@@ -50,7 +61,7 @@ This is the technology that Shoelace is built on.
## What Problem Does This Solve?
Shoelace provides a collection of professionally designed, every day UI components built on a framework-agnostic technology. Why spend hundreds of hours or more building a design system from scratch? Why make a component library that only works with one framework?
Shoelace provides a collection of professionally designed, every day UI components built on a framework-agnostic technology. Why spend hundreds of hours (or more) building a design system from scratch? Why make a component library that only works with one framework?
With Shoelace, you can:
@@ -68,11 +79,11 @@ Whether you use Shoelace as a starting point for your organization's design syst
Shoelace is tested in the latest two versions of the following browsers.
<img src="/assets/images/chrome.png" alt="Chrome" width="64" height="64" data-no-zoom>
<img src="/assets/images/edge.png" alt="Edge" width="64" height="64" data-no-zoom>
<img src="/assets/images/firefox.png" alt="Firefox" width="64" height="64" data-no-zoom>
<img src="/assets/images/opera.png" alt="Opera" width="64" height="64" data-no-zoom>
<img src="/assets/images/safari.png" alt="Safari" width="64" height="64" data-no-zoom>
<img src="/assets/images/chrome.png" alt="Chrome" width="64" height="64">
<img src="/assets/images/edge.png" alt="Edge" width="64" height="64">
<img src="/assets/images/firefox.png" alt="Firefox" width="64" height="64">
<img src="/assets/images/opera.png" alt="Opera" width="64" height="64">
<img src="/assets/images/safari.png" alt="Safari" width="64" height="64">
Critical bug fixes in earlier versions will be addressed based on their severity and impact.
@@ -82,33 +93,35 @@ If you need to support IE11 or pre-Chromium Edge, this library isn't for you. Al
Shoelace is designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska). It's available under the terms of the MIT license.
Designing, developing, and supporting this library requires a lot of time, effort, and skill. I'd like to keep it open source so everyone can use it, but that doesn't provide me with any income.
**Therefore, if you're using my software to make a profit,** I respectfully ask that you help [fund its development](https://github.com/sponsors/claviska) by becoming a sponsor. There are multiple tiers to choose from with benefits at every level, including prioritized support, bug fixes, feature requests, and advertising.
Designing, developing, and supporting this library requires a lot of time, effort, and skill. If you're using this software to make a profit, I respectfully ask that you help [fund its development](https://github.com/sponsors/claviska) by becoming a sponsor.
👇 Your support is very much appreciated! 👇
<a class="repo-button repo-button--sponsor" href="https://github.com/sponsors/claviska" rel="noopener" target="_blank">
<sl-button class="repo-button repo-button--sponsor" href="https://github.com/sponsors/claviska" target="_blank">
<sl-icon name="heart"></sl-icon> Become a sponsor
</a>
</sl-button>
<a class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace/stargazers" rel="noopener" target="_blank">
<sl-icon src="/assets/images/github.svg"></sl-icon> Star
</a>
<sl-button class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace/stargazers" target="_blank">
<sl-icon name="github"></sl-icon> <span class="github-star-count">Star</span>
</sl-button>
<a class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" rel="noopener" target="_blank">
<sl-icon src="/assets/images/twitter.svg"></sl-icon> Follow
</a>
<sl-button class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" target="_blank">
<sl-icon name="twitter"></sl-icon> Follow
</sl-button>
## Attribution
Special thanks to the following projects and individuals that helped make Shoelace possible.
Special thanks to the following projects and individuals that help make Shoelace possible.
- Components are compiled by [Stencil](https://stenciljs.com/)
- Components are built with [LitElement](https://lit-element.polymer-project.org/)
- Component metadata is generated by the [Custom Elements Manifest Analyzer](https://github.com/open-wc/custom-elements-manifest)
- Documentation is powered by [Docsify](https://docsify.js.org/)
- Theme colors and form controls are inspired by [Element](https://element.eleme.io/)
- CDN services are provided by [jsDelivr](https://www.jsdelivr.com/)
- Color primitives are derived from [Tailwind](https://tailwindcss.com/)
- Icons are courtesy of [Bootstrap Icons](https://icons.getbootstrap.com/)
- Illustrations are courtesy of [unDraw](https://undraw.co/)
- The homepage illustration is courtesy of [unDraw](https://undraw.co/)
- Positioning of menus, tooltips, et al is handled by [Popper.js](https://popper.js.org/)
- CDN services are provided by [unpkg](https://unpkg.com/)
- Animations are courtesy of [animate.css](https://animate.style/)
- QR codes are generated with [qr-creator](https://github.com/nimiq/qr-creator)
- Search is powered by [Lunr](https://lunrjs.com/)
- The Shoelace logo was designed with a single shoelace by [Adam K Olson](https://twitter.com/adamkolson)

View File

@@ -1,41 +0,0 @@
# Roadmap
The roadmap tracks the status of components and features that are planned for development.
## 2.1 🤔
Version 2.1 is still in the planning phase. To request a feature, please [submit an issue](https://github.com/shoelace-style/shoelace/issues) on GitHub. Make sure to search for existing issues and vote using 👍 to add your support!
?> Is there a feature you really want to see here? Sponsoring Shoelace is the best way to prioritize its development. [Learn more](https://github.com/sponsors/claviska)
## 2.0 🚀
- [x] Alert
- [x] Avatar
- [x] Button
- [x] Checkbox
- [x] Color Picker
- [x] Details
- [x] Dialog
- [x] Drawer
- [x] Dropdown
- [x] Form
- [x] Icon
- [x] Input
- [x] Menu
- [x] Menu Divider
- [x] Menu Item
- [x] Menu Label
- [x] Progress Bar
- [x] Progress Ring
- [x] Radio
- [x] Range
- [x] Select
- [x] Spinner
- [x] Switch
- [x] Tab Group
- [x] Tab
- [x] Tab Panel
- [x] Tag
- [x] Textarea
- [x] Tooltip

View File

@@ -0,0 +1,137 @@
# Themes
Shoelace is designed to be highly customizable through pure CSS. Out of the box, you can choose from a light or dark theme. Alternatively, you can design your own theme from scratch.
A theme is nothing more than a stylesheet that uses the Shoelace API to define design tokens and apply custom styles to components. To create a theme, you will need a decent understanding of CSS, including [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) and the [`::part` selector](https://developer.mozilla.org/en-US/docs/Web/CSS/::part).
For developers, built-in themes are also available as JavaScript modules that export [Lit CSSResult](https://lit.dev/docs/api/styles/#CSSResult) objects. You can find them in `dist/themes/*.styles.js`.
## Theme Basics
All themes are scoped to classes using the `sl-theme-{name}` convention, where `{name}` is a lowercase, hyphen-delimited value representing the name of the theme. The included light and dark themes use `sl-theme-light` and `sl-theme-dark`, respectively. A custom theme called "Purple Power", for example, would use the `sl-theme-purple-power` class.
Every selector must be scoped to the theme's class to ensure interoperability with other themes. You should also scope them to `:host` so they can be imported and applied to custom element shadow roots.
```css
:host,
.sl-theme-purple-power {
/* ... */
}
```
### Activating Themes
To activate a theme, import it and apply the theme's class to the `<html>` element. This example imports and activates the dark theme, or "dark mode."
```html
<html class="sl-theme-dark">
<head>
<link rel="stylesheet" href="path/to/shoelace/dist/themes/dark.css">
</head>
<body>
...
</body>
</html>
```
?> There is one exception to this rule — the light theme _does not_ need to be activated. For convenience, the light theme is scoped to `:root` and will be activated by default when imported.
### Using Multiple Themes
You can activate themes on various containers throughout the page. This example uses the light theme with a dark-themed sidebar.
```html
<html>
<head>
<link rel="stylesheet" href="path/to/shoelace/dist/themes/light.css">
<link rel="stylesheet" href="path/to/shoelace/dist/themes/dark.css">
</head>
<body>
<nav class="sl-theme-dark">
<!-- dark-themed sidebar -->
</nav>
<!-- light-themed content -->
</body>
</html>
```
## Creating Themes
There are two ways to create themes. The easiest way is to customize a built-in theme. The advanced way is to create a new theme from scratch. Which method you choose depends on your project's requirements and the amount of effort you're willing to commit to.
### Customizing a Built-in Theme
The easiest way to customize Shoelace is to override one of the built-in themes. You can do this by importing the light or dark theme as-is, then creating a separate stylesheet that overrides the [design tokens](/getting-started/customizing#design-tokens) and adds [component styles](/getting-started/customizing#component-parts) to your liking. You must import your theme _after_ the built-in theme.
If you're customizing the light theme, you should scope your styles to the following selectors.
```css
:root,
:host,
.sl-theme-light {
/* your custom styles here */
}
```
If you're customizing the dark theme, you should scope your styles to the following selectors.
```css
:host,
.sl-theme-dark {
/* your custom styles here */
}
```
By customizing a built-in theme, you'll maintain a smaller stylesheet containing only the changes you've made. Contrast this to [creating a new theme](#creating-a-new-theme), where you need to explicitly define every design token required by the library. This approach is more "future-proof," as new design tokens that emerge in subsequent versions of Shoelace will be accounted for by the built-in theme.
While this may be easier to maintain, the drawback is that your theme modifies a built-in theme and thus can't be activated independently.
### Creating a New Theme
Creating a new theme is more of an undertaking than [customizing an existing one](#customizing-a-built-in-theme). At a minimum, you must implement all of the required design tokens. The easiest way to do this is by "forking" one of the built-in themes and modifying it from there.
Start by changing the selector to match your theme's name. Assuming your new theme is called "Purple Power", your theme should be scoped like this.
```css
:host,
.sl-theme-purple-power {
/* your custom styles here */
}
```
By creating a new theme, you won't be relying on a built-in theme as a foundation. Because the theme is decoupled from the built-ins, you can activate it independently as an alternative to the built-ins. This is the recommended approach if you're looking to open source your theme for others to use.
You will, however, need to maintain your theme more carefully, as new versions of Shoelace may introduce new design tokens that your theme won't have accounted for. Because of this, it's recommended that you clearly specify which version(s) of Shoelace your theme is designed to work with and keep it up to date as new versions of Shoelace are released.
## Dark Theme
The built-in dark theme uses an inverted + shifted color scale so, if you're using design tokens as intended, you'll get a decent dark mode for free. While this isn't the same as a professionally curated dark theme, it provides an excellent baseline for one and you're encouraged to customize it depending on your needs.
This was achieved by taking the light theme's [color tokens](/tokens/color) and "flipping" the scale so 100 becomes 900, 200 becomes 800, 300 becomes 700, etc. Next, the luminance of each primitive was increased slightly to avoid true black, a color that is typically undesirable in dark themes. The result is a custom palette that complements the light theme well and makes it easy to offer light and dark variations with minimal effort.
To install the dark theme, add the following to the `<head>` section of your page.
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/dark.css">
```
To activate the theme, apply the `sl-theme-dark` class to the `<html>` element.
```html
<html class="sl-theme-dark">
...
</html>
```
### Detecting the User's Color Scheme Preference
Shoelace doesn't try to auto-detect the user's light/dark mode preference. This should be done at the application level. As a best practice, to provide a dark theme in your app, you should:
- Check for [`prefers-color-scheme`](https://stackoverflow.com/a/57795495/567486) and use its value by default
- Allow the user to override the setting in your app
- Remember the user's preference and restore it on subsequent logins
Shoelace avoids using the `prefers-color-scheme` media query because not all apps support dark mode, and it would break things for the ones that don't.

Some files were not shown because too many files have changed in this diff Show More