@mhmo91/schmancy 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/.claude-plugin/plugin.json +13 -0
  2. package/README.md +14 -4
  3. package/dist/.claude-plugin/plugin.json +13 -0
  4. package/dist/skills/SKILL.md +120 -0
  5. package/dist/skills/schmancy/SKILL.md +120 -0
  6. package/package.json +3 -3
  7. package/skills/schmancy/INDEX.md +72 -0
  8. package/skills/schmancy/SKILL.md +120 -0
  9. package/skills/schmancy/animation.md +64 -0
  10. package/skills/schmancy/area.md +141 -0
  11. package/skills/schmancy/audio.md +69 -0
  12. package/skills/schmancy/autocomplete.md +53 -0
  13. package/skills/schmancy/avatar.md +47 -0
  14. package/skills/schmancy/badge.md +41 -0
  15. package/skills/schmancy/boat.md +47 -0
  16. package/skills/schmancy/busy.md +36 -0
  17. package/skills/schmancy/button.md +59 -0
  18. package/skills/schmancy/card.md +53 -0
  19. package/skills/schmancy/charts.md +93 -0
  20. package/skills/schmancy/checkbox.md +36 -0
  21. package/skills/schmancy/chips.md +87 -0
  22. package/skills/schmancy/code-highlight.md +47 -0
  23. package/skills/schmancy/connectivity.md +36 -0
  24. package/skills/schmancy/content-drawer.md +65 -0
  25. package/skills/schmancy/date-range-inline.md +44 -0
  26. package/skills/schmancy/date-range.md +50 -0
  27. package/skills/schmancy/delay.md +50 -0
  28. package/skills/schmancy/details.md +66 -0
  29. package/skills/schmancy/dialog.md +69 -0
  30. package/skills/schmancy/directives.md +298 -0
  31. package/skills/schmancy/discovery.md +67 -0
  32. package/skills/schmancy/divider.md +31 -0
  33. package/skills/schmancy/dropdown.md +47 -0
  34. package/skills/schmancy/expand.md +63 -0
  35. package/skills/schmancy/extra.md +59 -0
  36. package/skills/schmancy/float.md +14 -0
  37. package/skills/schmancy/form.md +49 -0
  38. package/skills/schmancy/icons.md +44 -0
  39. package/skills/schmancy/iframe.md +44 -0
  40. package/skills/schmancy/input.md +56 -0
  41. package/skills/schmancy/json.md +33 -0
  42. package/skills/schmancy/layout.md +63 -0
  43. package/skills/schmancy/lightbox.md +36 -0
  44. package/skills/schmancy/list.md +67 -0
  45. package/skills/schmancy/mailbox.md +102 -0
  46. package/skills/schmancy/map.md +55 -0
  47. package/skills/schmancy/menu.md +39 -0
  48. package/skills/schmancy/mixins.md +99 -0
  49. package/skills/schmancy/nav-drawer.md +52 -0
  50. package/skills/schmancy/navigation-bar.md +48 -0
  51. package/skills/schmancy/navigation-rail.md +62 -0
  52. package/skills/schmancy/notification.md +60 -0
  53. package/skills/schmancy/option.md +43 -0
  54. package/skills/schmancy/page.md +42 -0
  55. package/skills/schmancy/progress.md +30 -0
  56. package/skills/schmancy/qr-scanner.md +51 -0
  57. package/skills/schmancy/radio-group.md +50 -0
  58. package/skills/schmancy/range.md +47 -0
  59. package/skills/schmancy/rxjs-utils.md +60 -0
  60. package/skills/schmancy/select.md +49 -0
  61. package/skills/schmancy/sheet.md +76 -0
  62. package/skills/schmancy/slider.md +43 -0
  63. package/skills/schmancy/steps.md +53 -0
  64. package/skills/schmancy/store.md +126 -0
  65. package/skills/schmancy/surface.md +86 -0
  66. package/skills/schmancy/table.md +60 -0
  67. package/skills/schmancy/tabs.md +49 -0
  68. package/skills/schmancy/teleport.md +55 -0
  69. package/skills/schmancy/textarea.md +48 -0
  70. package/skills/schmancy/theme-button.md +26 -0
  71. package/skills/schmancy/theme.md +58 -0
  72. package/skills/schmancy/tooltip.md +38 -0
  73. package/skills/schmancy/tree.md +53 -0
  74. package/skills/schmancy/typewriter.md +46 -0
  75. package/skills/schmancy/typography.md +53 -0
  76. package/skills/schmancy/utils.md +95 -0
  77. package/skills/schmancy/window.md +67 -0
  78. /package/{ai → dist/skills}/INDEX.md +0 -0
  79. /package/{ai → dist/skills}/animation.md +0 -0
  80. /package/{ai → dist/skills}/area.md +0 -0
  81. /package/{ai → dist/skills}/audio.md +0 -0
  82. /package/{ai → dist/skills}/autocomplete.md +0 -0
  83. /package/{ai → dist/skills}/avatar.md +0 -0
  84. /package/{ai → dist/skills}/badge.md +0 -0
  85. /package/{ai → dist/skills}/boat.md +0 -0
  86. /package/{ai → dist/skills}/busy.md +0 -0
  87. /package/{ai → dist/skills}/button.md +0 -0
  88. /package/{ai → dist/skills}/card.md +0 -0
  89. /package/{ai → dist/skills}/charts.md +0 -0
  90. /package/{ai → dist/skills}/checkbox.md +0 -0
  91. /package/{ai → dist/skills}/chips.md +0 -0
  92. /package/{ai → dist/skills}/code-highlight.md +0 -0
  93. /package/{ai → dist/skills}/connectivity.md +0 -0
  94. /package/{ai → dist/skills}/content-drawer.md +0 -0
  95. /package/{ai → dist/skills}/date-range-inline.md +0 -0
  96. /package/{ai → dist/skills}/date-range.md +0 -0
  97. /package/{ai → dist/skills}/delay.md +0 -0
  98. /package/{ai → dist/skills}/details.md +0 -0
  99. /package/{ai → dist/skills}/dialog.md +0 -0
  100. /package/{ai → dist/skills}/directives.md +0 -0
  101. /package/{ai → dist/skills}/discovery.md +0 -0
  102. /package/{ai → dist/skills}/divider.md +0 -0
  103. /package/{ai → dist/skills}/dropdown.md +0 -0
  104. /package/{ai → dist/skills}/expand.md +0 -0
  105. /package/{ai → dist/skills}/extra.md +0 -0
  106. /package/{ai → dist/skills}/float.md +0 -0
  107. /package/{ai → dist/skills}/form.md +0 -0
  108. /package/{ai → dist/skills}/icons.md +0 -0
  109. /package/{ai → dist/skills}/iframe.md +0 -0
  110. /package/{ai → dist/skills}/input.md +0 -0
  111. /package/{ai → dist/skills}/json.md +0 -0
  112. /package/{ai → dist/skills}/layout.md +0 -0
  113. /package/{ai → dist/skills}/lightbox.md +0 -0
  114. /package/{ai → dist/skills}/list.md +0 -0
  115. /package/{ai → dist/skills}/mailbox.md +0 -0
  116. /package/{ai → dist/skills}/map.md +0 -0
  117. /package/{ai → dist/skills}/menu.md +0 -0
  118. /package/{ai → dist/skills}/mixins.md +0 -0
  119. /package/{ai → dist/skills}/nav-drawer.md +0 -0
  120. /package/{ai → dist/skills}/navigation-bar.md +0 -0
  121. /package/{ai → dist/skills}/navigation-rail.md +0 -0
  122. /package/{ai → dist/skills}/notification.md +0 -0
  123. /package/{ai → dist/skills}/option.md +0 -0
  124. /package/{ai → dist/skills}/page.md +0 -0
  125. /package/{ai → dist/skills}/progress.md +0 -0
  126. /package/{ai → dist/skills}/qr-scanner.md +0 -0
  127. /package/{ai → dist/skills}/radio-group.md +0 -0
  128. /package/{ai → dist/skills}/range.md +0 -0
  129. /package/{ai → dist/skills}/rxjs-utils.md +0 -0
  130. /package/dist/{ai → skills/schmancy}/INDEX.md +0 -0
  131. /package/dist/{ai → skills/schmancy}/animation.md +0 -0
  132. /package/dist/{ai → skills/schmancy}/area.md +0 -0
  133. /package/dist/{ai → skills/schmancy}/audio.md +0 -0
  134. /package/dist/{ai → skills/schmancy}/autocomplete.md +0 -0
  135. /package/dist/{ai → skills/schmancy}/avatar.md +0 -0
  136. /package/dist/{ai → skills/schmancy}/badge.md +0 -0
  137. /package/dist/{ai → skills/schmancy}/boat.md +0 -0
  138. /package/dist/{ai → skills/schmancy}/busy.md +0 -0
  139. /package/dist/{ai → skills/schmancy}/button.md +0 -0
  140. /package/dist/{ai → skills/schmancy}/card.md +0 -0
  141. /package/dist/{ai → skills/schmancy}/charts.md +0 -0
  142. /package/dist/{ai → skills/schmancy}/checkbox.md +0 -0
  143. /package/dist/{ai → skills/schmancy}/chips.md +0 -0
  144. /package/dist/{ai → skills/schmancy}/code-highlight.md +0 -0
  145. /package/dist/{ai → skills/schmancy}/connectivity.md +0 -0
  146. /package/dist/{ai → skills/schmancy}/content-drawer.md +0 -0
  147. /package/dist/{ai → skills/schmancy}/date-range-inline.md +0 -0
  148. /package/dist/{ai → skills/schmancy}/date-range.md +0 -0
  149. /package/dist/{ai → skills/schmancy}/delay.md +0 -0
  150. /package/dist/{ai → skills/schmancy}/details.md +0 -0
  151. /package/dist/{ai → skills/schmancy}/dialog.md +0 -0
  152. /package/dist/{ai → skills/schmancy}/directives.md +0 -0
  153. /package/dist/{ai → skills/schmancy}/discovery.md +0 -0
  154. /package/dist/{ai → skills/schmancy}/divider.md +0 -0
  155. /package/dist/{ai → skills/schmancy}/dropdown.md +0 -0
  156. /package/dist/{ai → skills/schmancy}/expand.md +0 -0
  157. /package/dist/{ai → skills/schmancy}/extra.md +0 -0
  158. /package/dist/{ai → skills/schmancy}/float.md +0 -0
  159. /package/dist/{ai → skills/schmancy}/form.md +0 -0
  160. /package/dist/{ai → skills/schmancy}/icons.md +0 -0
  161. /package/dist/{ai → skills/schmancy}/iframe.md +0 -0
  162. /package/dist/{ai → skills/schmancy}/input.md +0 -0
  163. /package/dist/{ai → skills/schmancy}/json.md +0 -0
  164. /package/dist/{ai → skills/schmancy}/layout.md +0 -0
  165. /package/dist/{ai → skills/schmancy}/lightbox.md +0 -0
  166. /package/dist/{ai → skills/schmancy}/list.md +0 -0
  167. /package/dist/{ai → skills/schmancy}/mailbox.md +0 -0
  168. /package/dist/{ai → skills/schmancy}/map.md +0 -0
  169. /package/dist/{ai → skills/schmancy}/menu.md +0 -0
  170. /package/dist/{ai → skills/schmancy}/mixins.md +0 -0
  171. /package/dist/{ai → skills/schmancy}/nav-drawer.md +0 -0
  172. /package/dist/{ai → skills/schmancy}/navigation-bar.md +0 -0
  173. /package/dist/{ai → skills/schmancy}/navigation-rail.md +0 -0
  174. /package/dist/{ai → skills/schmancy}/notification.md +0 -0
  175. /package/dist/{ai → skills/schmancy}/option.md +0 -0
  176. /package/dist/{ai → skills/schmancy}/page.md +0 -0
  177. /package/dist/{ai → skills/schmancy}/progress.md +0 -0
  178. /package/dist/{ai → skills/schmancy}/qr-scanner.md +0 -0
  179. /package/dist/{ai → skills/schmancy}/radio-group.md +0 -0
  180. /package/dist/{ai → skills/schmancy}/range.md +0 -0
  181. /package/dist/{ai → skills/schmancy}/rxjs-utils.md +0 -0
  182. /package/{ai → dist/skills/schmancy}/select.md +0 -0
  183. /package/{ai → dist/skills/schmancy}/sheet.md +0 -0
  184. /package/{ai → dist/skills/schmancy}/slider.md +0 -0
  185. /package/{ai → dist/skills/schmancy}/steps.md +0 -0
  186. /package/{ai → dist/skills/schmancy}/store.md +0 -0
  187. /package/{ai → dist/skills/schmancy}/surface.md +0 -0
  188. /package/{ai → dist/skills/schmancy}/table.md +0 -0
  189. /package/{ai → dist/skills/schmancy}/tabs.md +0 -0
  190. /package/{ai → dist/skills/schmancy}/teleport.md +0 -0
  191. /package/{ai → dist/skills/schmancy}/textarea.md +0 -0
  192. /package/{ai → dist/skills/schmancy}/theme-button.md +0 -0
  193. /package/{ai → dist/skills/schmancy}/theme.md +0 -0
  194. /package/{ai → dist/skills/schmancy}/tooltip.md +0 -0
  195. /package/{ai → dist/skills/schmancy}/tree.md +0 -0
  196. /package/{ai → dist/skills/schmancy}/typewriter.md +0 -0
  197. /package/{ai → dist/skills/schmancy}/typography.md +0 -0
  198. /package/{ai → dist/skills/schmancy}/utils.md +0 -0
  199. /package/{ai → dist/skills/schmancy}/window.md +0 -0
  200. /package/dist/{ai → skills}/select.md +0 -0
  201. /package/dist/{ai → skills}/sheet.md +0 -0
  202. /package/dist/{ai → skills}/slider.md +0 -0
  203. /package/dist/{ai → skills}/steps.md +0 -0
  204. /package/dist/{ai → skills}/store.md +0 -0
  205. /package/dist/{ai → skills}/surface.md +0 -0
  206. /package/dist/{ai → skills}/table.md +0 -0
  207. /package/dist/{ai → skills}/tabs.md +0 -0
  208. /package/dist/{ai → skills}/teleport.md +0 -0
  209. /package/dist/{ai → skills}/textarea.md +0 -0
  210. /package/dist/{ai → skills}/theme-button.md +0 -0
  211. /package/dist/{ai → skills}/theme.md +0 -0
  212. /package/dist/{ai → skills}/tooltip.md +0 -0
  213. /package/dist/{ai → skills}/tree.md +0 -0
  214. /package/dist/{ai → skills}/typewriter.md +0 -0
  215. /package/dist/{ai → skills}/typography.md +0 -0
  216. /package/dist/{ai → skills}/utils.md +0 -0
  217. /package/dist/{ai → skills}/window.md +0 -0
@@ -0,0 +1,48 @@
1
+ # schmancy-navigation-bar
2
+
3
+ > Horizontal bottom navigation bar for mobile with 3-7 destinations, auto-hide on scroll, and fullscreen support.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-navigation-bar activeIndex="0" class="fixed bottom-0 left-0 right-0">
8
+ <schmancy-navigation-bar-item icon="home" label="Home"></schmancy-navigation-bar-item>
9
+ <schmancy-navigation-bar-item icon="search" label="Search"></schmancy-navigation-bar-item>
10
+ <schmancy-navigation-bar-item icon="settings" label="Settings"></schmancy-navigation-bar-item>
11
+ </schmancy-navigation-bar>
12
+ ```
13
+
14
+ ## Properties (schmancy-navigation-bar)
15
+ | Property | Type | Default | Description |
16
+ |----------|------|---------|-------------|
17
+ | activeIndex | number | `-1` | Currently active item index |
18
+ | hideLabels | boolean | `false` | Hide labels, show only icons |
19
+ | elevation | number (0-5) | `2` | Shadow elevation |
20
+ | hideOnScroll | boolean | `false` | Auto-hide on scroll down |
21
+
22
+ ## Properties (schmancy-navigation-bar-item)
23
+ | Property | Type | Default | Description |
24
+ |----------|------|---------|-------------|
25
+ | icon | string | `''` | Material Symbols icon name |
26
+ | label | string | `''` | Item label text |
27
+ | badge | string | `''` | Badge content (number or text) |
28
+ | active | boolean | `false` | Whether this item is active |
29
+ | disabled | boolean | `false` | Whether this item is disabled |
30
+ | hideLabels | boolean | `false` | Whether to hide the label |
31
+
32
+ ## Events
33
+ | Event | Detail | Description |
34
+ |-------|--------|-------------|
35
+ | navigation-change | `{ oldIndex, newIndex, item }` | When active item changes |
36
+
37
+ ## Examples
38
+ ```html
39
+ <!-- With badges and scroll-hide -->
40
+ <schmancy-navigation-bar activeIndex="0" hideOnScroll>
41
+ <schmancy-navigation-bar-item icon="inbox" label="Inbox" badge="5">
42
+ </schmancy-navigation-bar-item>
43
+ <schmancy-navigation-bar-item icon="favorite" label="Favorites">
44
+ </schmancy-navigation-bar-item>
45
+ </schmancy-navigation-bar>
46
+ ```
47
+
48
+ Automatically hides in fullscreen mode. Consumer must position the bar (e.g., `class="fixed bottom-0 left-0 right-0"`).
@@ -0,0 +1,62 @@
1
+ # schmancy-navigation-rail
2
+
3
+ > Vertical navigation rail for desktop with 3-7 destinations, expand/collapse, and badge support.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-navigation-rail activeIndex="0">
8
+ <schmancy-navigation-rail-item icon="home" label="Home"></schmancy-navigation-rail-item>
9
+ <schmancy-navigation-rail-item icon="search" label="Search"></schmancy-navigation-rail-item>
10
+ <schmancy-navigation-rail-item icon="settings" label="Settings"></schmancy-navigation-rail-item>
11
+ </schmancy-navigation-rail>
12
+ ```
13
+
14
+ ## Properties (schmancy-navigation-rail)
15
+ | Property | Type | Default | Description |
16
+ |----------|------|---------|-------------|
17
+ | activeIndex | number | `-1` | Currently active item index |
18
+ | activeValue | string | `''` | Active item by value string |
19
+ | labelVisibility | `'all'\|'selected'\|'none'` | `'all'` | When to show labels |
20
+ | alignment | `'top'\|'center'\|'bottom'` | `'top'` | Item vertical alignment |
21
+ | expanded | boolean | `false` | Expanded width (240px vs 80px) |
22
+ | keyboardNavigation | boolean | `true` | Enable arrow key navigation |
23
+
24
+ ## Slots
25
+ | Slot | Description |
26
+ |------|-------------|
27
+ | fab | Floating action button at top |
28
+ | menu | Menu button below FAB |
29
+ | header | Custom header content |
30
+ | footer | Custom footer content |
31
+ | default | Navigation rail items |
32
+
33
+ ## Properties (schmancy-navigation-rail-item)
34
+ | Property | Type | Default | Description |
35
+ |----------|------|---------|-------------|
36
+ | icon | string | `''` | Material Symbols icon name |
37
+ | label | string | `''` | Item label text |
38
+ | value | string | `''` | Value for routing |
39
+ | active | boolean | `false` | Whether active |
40
+ | badge | string | `''` | Badge text |
41
+ | badgeVariant | `'error'\|'primary'\|'secondary'` | `'error'` | Badge color |
42
+ | disabled | boolean | `false` | Whether disabled |
43
+
44
+ ## Events
45
+ | Event | Detail | Description |
46
+ |-------|--------|-------------|
47
+ | navigate | string | Item value when clicked |
48
+
49
+ ## Examples
50
+ ```html
51
+ <schmancy-navigation-rail activeIndex="0" alignment="top">
52
+ <schmancy-button slot="fab" variant="filled">
53
+ <schmancy-icon>add</schmancy-icon>
54
+ </schmancy-button>
55
+ <schmancy-navigation-rail-item icon="dashboard" label="Dashboard" value="dash">
56
+ </schmancy-navigation-rail-item>
57
+ <schmancy-navigation-rail-item icon="people" label="Users" value="users" badge="3">
58
+ </schmancy-navigation-rail-item>
59
+ </schmancy-navigation-rail>
60
+ ```
61
+
62
+ Automatically hides in fullscreen mode. Width is 80px collapsed, 240px expanded.
@@ -0,0 +1,60 @@
1
+ # $notify
2
+
3
+ > Notification service with type-colored luminous glow, progress bar countdown, and arc-path entry animation.
4
+
5
+ ## Usage
6
+ ```typescript
7
+ import { $notify } from '@mhmo91/schmancy'
8
+
9
+ $notify.success('Item saved')
10
+ $notify.error('Failed to connect')
11
+ ```
12
+
13
+ ## $notify API
14
+ | Method | Returns | Description |
15
+ |--------|---------|-------------|
16
+ | `success(message?, options?)` | `string` (id) | Green glow, 1.5s duration |
17
+ | `error(message?, options?)` | `string` (id) | Red glow, 2.5s duration |
18
+ | `warning(message?, options?)` | `string` (id) | Orange glow, 2.5s duration |
19
+ | `info(message?, options?)` | `string` (id) | Blue glow, 2s duration |
20
+ | `show(options)` | `string` (id) | Full options control |
21
+ | `persistent(message, options?)` | `string` (id) | No auto-dismiss (duration: 0) |
22
+ | `customDuration(msg, ms, options?)` | `string` (id) | Custom duration in ms |
23
+ | `dismiss(id?)` | `void` | Dismiss by id or most recent |
24
+ | `update(id, options)` | `void` | Update existing notification content |
25
+
26
+ ## Options
27
+ | Option | Type | Default | Description |
28
+ |--------|------|---------|-------------|
29
+ | `message` | `string` | required | Notification body text |
30
+ | `title` | `string` | `undefined` | Optional title line |
31
+ | `type` | `'info' \| 'success' \| 'warning' \| 'error'` | `'info'` | Notification type |
32
+ | `duration` | `number` | Type-specific | Auto-dismiss ms (0 = persistent) |
33
+ | `closable` | `boolean` | `true` | Show close button |
34
+ | `playSound` | `boolean` | `true` | Play type-specific sound |
35
+ | `showProgress` | `boolean` | `false` | Show indeterminate progress bar |
36
+
37
+ ## Physics
38
+ - Type-colored luminous glow shadow (18% intensity, 28% on hover)
39
+ - Arc-path entry animation from last click position to top-right corner
40
+ - Hover: glow intensifies + `translateY(-2px)` lift
41
+ - Progress bar shows countdown timer; pauses on hover
42
+ - Only one notification visible at a time (replaces previous)
43
+
44
+ ## Examples
45
+ ```typescript
46
+ // Success with title
47
+ $notify.success('Changes saved', { title: 'Success' })
48
+
49
+ // Persistent loading indicator
50
+ const id = $notify.persistent('Processing...', { showProgress: true })
51
+ // Later: dismiss it
52
+ $notify.dismiss(id)
53
+
54
+ // Error with longer duration
55
+ $notify.error('Connection lost', { duration: 5000 })
56
+
57
+ // Update existing notification
58
+ const nid = $notify.info('Uploading...')
59
+ $notify.update(nid, { message: 'Upload complete', type: 'success' })
60
+ ```
@@ -0,0 +1,43 @@
1
+ # schmancy-option
2
+
3
+ > Selectable item for `schmancy-select`, `schmancy-autocomplete`, and `schmancy-menu`. Lightweight and a11y-ready.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-select label="Country">
8
+ <schmancy-option value="us">United States</schmancy-option>
9
+ <schmancy-option value="de">Germany</schmancy-option>
10
+ <schmancy-option value="jp" disabled>Japan</schmancy-option>
11
+ </schmancy-select>
12
+ ```
13
+
14
+ ## Properties
15
+ | Property | Type | Default | Description |
16
+ |----------|------|---------|-------------|
17
+ | `value` | string | `''` | Value reported when this option is selected |
18
+ | `label` | string | auto | Display label (falls back to text content) |
19
+ | `selected` | boolean | `false` | Reflects selected state |
20
+ | `disabled` | boolean | `false` | Disables interaction |
21
+ | `group` | string | `''` | Grouping identifier for grouped lists |
22
+ | `icon` | string | `''` | Material icon name before the label |
23
+
24
+ ## Events
25
+ | Event | Payload | When |
26
+ |-------|---------|------|
27
+ | `click` | — | Standard click event |
28
+ | `option-select` | `CustomEvent<{ value, label }>` | Dispatched on activation |
29
+
30
+ ## Behavior
31
+ - Auto-generates `id` for ARIA wiring if not set.
32
+ - Infers `label` from text content when omitted.
33
+ - Keyboard focusable with a visible focus ring via `:focus-visible`.
34
+ - Parent select/autocomplete coordinates selection state via slot query.
35
+
36
+ ## Example — grouped options
37
+ ```html
38
+ <schmancy-select label="Framework">
39
+ <schmancy-option value="lit" group="web" icon="bolt">Lit</schmancy-option>
40
+ <schmancy-option value="react" group="web">React</schmancy-option>
41
+ <schmancy-option value="swift" group="mobile">Swift</schmancy-option>
42
+ </schmancy-select>
43
+ ```
@@ -0,0 +1,42 @@
1
+ # schmancy-page
2
+
3
+ > Native mobile-like page container. Fills remaining viewport height, prevents rubber-banding, pull-to-refresh, and double-tap zoom.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-page rows="auto_1fr_auto">
8
+ <header>App bar</header>
9
+ <main>Scrollable content</main>
10
+ <footer>Bottom nav</footer>
11
+ </schmancy-page>
12
+ ```
13
+
14
+ ## Properties
15
+ | Property | Type | Default | Description |
16
+ |----------|------|---------|-------------|
17
+ | `rows` | string | `'auto_1fr_auto'` | Grid template rows — underscores become spaces (e.g. `'1fr_2fr_auto'`) |
18
+ | `show-scrollbar` | boolean | `false` | Display scrollbar on scrollable area |
19
+ | `no-select` | boolean | `false` | Disable text selection |
20
+
21
+ ## Behavior
22
+ - Listens to `visualViewport` resize/scroll + `orientationchange` + keyboard focus events to recompute height.
23
+ - Accounts for theme bottom offset (iOS safe area, home indicator).
24
+ - Auto-assigns semantic elements (`header`, `main`, `footer`) to slots.
25
+ - Inner scroll area uses `schmancy-scroll` for momentum-preserving scroll.
26
+
27
+ ## When to Use
28
+ - Root of a mobile view or panel that should feel like a native page.
29
+ - Any container where viewport-aware height + scroll containment matters.
30
+
31
+ ## Example — 3-row app shell
32
+ ```html
33
+ <schmancy-page rows="auto_1fr_auto">
34
+ <schmancy-surface type="solid" rounded="none">
35
+ <schmancy-typography type="title">My App</schmancy-typography>
36
+ </schmancy-surface>
37
+
38
+ <div class="p-4">…scrollable content…</div>
39
+
40
+ <schmancy-navigation-bar></schmancy-navigation-bar>
41
+ </schmancy-page>
42
+ ```
@@ -0,0 +1,30 @@
1
+ # schmancy-progress
2
+
3
+ > Linear progress bar with determinate and indeterminate modes, color variants, and glass effect.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-progress value="60" max="100"></schmancy-progress>
8
+ ```
9
+
10
+ ## Properties
11
+ | Property | Type | Default | Description |
12
+ |----------|------|---------|-------------|
13
+ | value | number | `0` | Current progress value |
14
+ | max | number | `100` | Maximum value |
15
+ | indeterminate | boolean | `false` | Show indeterminate animation |
16
+ | size | `'xs'\|'sm'\|'md'\|'lg'` | `'md'` | Track height (1px, 2px, 4px, 8px) |
17
+ | color | `'primary'\|'secondary'\|'tertiary'\|'error'\|'success'` | `'primary'` | Bar color |
18
+ | glass | boolean | `false` | Glass/frosted effect |
19
+
20
+ ## Examples
21
+ ```html
22
+ <!-- Indeterminate loading -->
23
+ <schmancy-progress indeterminate color="secondary"></schmancy-progress>
24
+
25
+ <!-- Glass effect progress -->
26
+ <schmancy-progress value="75" glass size="lg" color="success"></schmancy-progress>
27
+
28
+ <!-- Thin track -->
29
+ <schmancy-progress value="30" size="xs"></schmancy-progress>
30
+ ```
@@ -0,0 +1,51 @@
1
+ # schmancy-qr-scanner
2
+
3
+ > Camera-based QR code scanner using `jsQR`. Requests rear-camera access, decodes frames in real time, deduplicates reads.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-qr-scanner
8
+ continuous
9
+ @scan-result=${e => this.handleScan(e.detail.data)}
10
+ ></schmancy-qr-scanner>
11
+ ```
12
+
13
+ ```typescript
14
+ handleScan(data: string) {
15
+ console.log('QR decoded:', data)
16
+ }
17
+ ```
18
+
19
+ ## Properties
20
+ | Property | Type | Default | Description |
21
+ |----------|------|---------|-------------|
22
+ | `continuous` | boolean | `true` | Keep scanning after a successful read (dedupe repeated reads) |
23
+
24
+ ## Events
25
+ | Event | Detail | When |
26
+ |-------|--------|------|
27
+ | `scan-result` | `{ data: string, timestamp: number }` | QR code successfully decoded |
28
+
29
+ ## Behavior
30
+ - Requests `getUserMedia` with `facingMode: 'environment'` (rear camera) at 1280×720.
31
+ - Decodes via `jsQR` on `animationFrames` stream with `throttleTime` to avoid CPU thrashing.
32
+ - `distinctUntilChanged` prevents duplicate emissions for the same code.
33
+ - Brief success flash on each valid read.
34
+ - Stops camera + tears down subscriptions on disconnect.
35
+ - Displays an error state if camera permission is denied.
36
+
37
+ ## Requires
38
+ - HTTPS (or `localhost`) for camera access.
39
+ - User permission to the camera.
40
+
41
+ ## Example
42
+ ```html
43
+ <schmancy-surface type="glass" rounded="all">
44
+ <schmancy-qr-scanner
45
+ @scan-result=${(e: CustomEvent<{ data: string }>) => {
46
+ $notify.success(`Scanned: ${e.detail.data}`)
47
+ this.scannedCode = e.detail.data
48
+ }}
49
+ ></schmancy-qr-scanner>
50
+ </schmancy-surface>
51
+ ```
@@ -0,0 +1,50 @@
1
+ # schmancy-radio-group
2
+
3
+ > Radio button group with options array or slotted radio buttons.
4
+
5
+ ## Usage
6
+ ```html
7
+ <!-- With options array -->
8
+ <schmancy-radio-group label="Size" name="size"
9
+ .options=${[{label: 'Small', value: 's'}, {label: 'Large', value: 'l'}]}
10
+ @change=${(e) => handle(e.detail.value)}>
11
+ </schmancy-radio-group>
12
+ ```
13
+
14
+ ## Properties (schmancy-radio-group)
15
+ | Property | Type | Default | Description |
16
+ |----------|------|---------|-------------|
17
+ | value | string | `''` | Currently selected value |
18
+ | label | string | `''` | Group label |
19
+ | name | string | `''` | Form submission name |
20
+ | options | `{label: string, value: string}[]` | `[]` | Radio options |
21
+ | required | boolean | `false` | Whether selection is required |
22
+
23
+ ## Events
24
+ | Event | Detail | Description |
25
+ |-------|--------|-------------|
26
+ | change | `{ value: string }` | When selection changes |
27
+
28
+ ## Properties (schmancy-radio-button)
29
+ | Property | Type | Default | Description |
30
+ |----------|------|---------|-------------|
31
+ | value | string | `''` | Button value |
32
+ | checked | boolean | `false` | Whether selected |
33
+ | disabled | boolean | `false` | Whether disabled |
34
+ | name | string | `''` | Group name |
35
+
36
+ ## Examples
37
+ ```html
38
+ <!-- With slotted radio buttons -->
39
+ <schmancy-radio-group label="Priority" name="priority" value="medium">
40
+ <schmancy-radio-button value="low">
41
+ <span slot="label">Low</span>
42
+ </schmancy-radio-button>
43
+ <schmancy-radio-button value="medium">
44
+ <span slot="label">Medium</span>
45
+ </schmancy-radio-button>
46
+ <schmancy-radio-button value="high">
47
+ <span slot="label">High</span>
48
+ </schmancy-radio-button>
49
+ </schmancy-radio-group>
50
+ ```
@@ -0,0 +1,47 @@
1
+ # schmancy-range
2
+
3
+ > Numeric slider input with theme-driven track gradient and focus halo.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-range
8
+ label="Volume"
9
+ min="0"
10
+ max="100"
11
+ step="1"
12
+ .value=${50}
13
+ @change=${e => this.volume = e.detail.value}
14
+ ></schmancy-range>
15
+ ```
16
+
17
+ ## Properties
18
+ | Property | Type | Default | Description |
19
+ |----------|------|---------|-------------|
20
+ | `min` | number | `0` | Minimum value |
21
+ | `max` | number | `1` | Maximum value |
22
+ | `step` | number | `0.01` | Increment per tick |
23
+ | `value` | number | `0` | Current value |
24
+ | `label` | string | — | Optional label (current value displays on the right) |
25
+ | `disabled` | boolean | `false` | Disabled state (38% opacity) |
26
+
27
+ ## Events
28
+ | Event | Payload | When |
29
+ |-------|---------|------|
30
+ | `change` | `{ value: number }` | On input change |
31
+
32
+ ## Visual
33
+ - Primary-colored track gradient (filled portion = primary, empty = 30% primary).
34
+ - Circular thumb with hover halo (8px primary glow at 12% opacity).
35
+ - Disabled state: 38% opacity, not-allowed cursor.
36
+
37
+ ## Example — precise float control
38
+ ```html
39
+ <schmancy-range
40
+ label="Mass"
41
+ min="0.5"
42
+ max="2.0"
43
+ step="0.05"
44
+ .value=${this.mass}
45
+ @change=${(e: CustomEvent<{ value: number }>) => this.mass = e.detail.value}
46
+ ></schmancy-range>
47
+ ```
@@ -0,0 +1,60 @@
1
+ # Schmancy RxJS Utils
2
+
3
+ > RxJS-wrapped DOM observation helpers. Use when you need to react to elements appearing, disappearing, or changing across the document.
4
+
5
+ ## Imports
6
+ ```typescript
7
+ import {
8
+ mutationObserver,
9
+ waitForElement,
10
+ waitForElementAll,
11
+ waitForElements,
12
+ waitForElementsAll,
13
+ waitUntil,
14
+ } from '@mhmo91/schmancy'
15
+ ```
16
+
17
+ ## `mutationObserver(target, options?)`
18
+ RxJS wrapper around `MutationObserver`.
19
+ ```typescript
20
+ mutationObserver(document.body, { childList: true, subtree: true })
21
+ .pipe(takeUntil(this.disconnecting))
22
+ .subscribe(mutations => { /* react */ })
23
+ ```
24
+
25
+ ## `waitForElement(selector, timeout = 5000)`
26
+ Emits the first matching element once it exists in the DOM. Throws on timeout. Pass `undefined` to wait forever.
27
+ ```typescript
28
+ waitForElement('#auth-banner').subscribe(el => el.focus())
29
+ waitForElement('.lazy-panel', 10000).subscribe(el => el.click())
30
+ ```
31
+
32
+ ## `waitForElementAll(selector, timeout?)`
33
+ Emits whenever the matching set changes (all current matches).
34
+ ```typescript
35
+ waitForElementAll('.live-tile').subscribe(tiles => {
36
+ tiles.forEach(t => observe(t))
37
+ })
38
+ ```
39
+
40
+ ## `waitForElements([sel1, sel2, ...], timeout?)` / `waitForElementsAll`
41
+ Multi-selector variants — resolve once *any*/`every` selector is present.
42
+
43
+ ## `waitUntil([selectors], timeout = 5000)`
44
+ Emits once when **all** selectors have matches. Throws on timeout.
45
+ ```typescript
46
+ waitUntil(['header', 'main', 'footer'])
47
+ .subscribe(() => console.log('Page shell ready'))
48
+ ```
49
+
50
+ ## How It Works
51
+ All helpers share `mutationObserver(document.body)` with `childList: true, subtree: true` and `.startWith(document.body)` so they check once immediately and re-check on every DOM mutation.
52
+
53
+ ## When to Use
54
+ - Integrating third-party scripts that inject DOM late.
55
+ - Coordinating with slot-projected children that may mount asynchronously.
56
+ - Awaiting app-shell elements before attaching shortcuts.
57
+
58
+ ## When NOT to Use
59
+ - Inside your own component — use `firstUpdated()` or `queryAssignedElements`.
60
+ - For cross-shadow discovery — use [discovery](./discovery.md) instead.
@@ -0,0 +1,49 @@
1
+ # schmancy-select
2
+
3
+ > Dropdown select with single and multi-select support, keyboard navigation, and form association.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-select label="Country" placeholder="Choose..." required>
8
+ <schmancy-option value="us" label="United States"></schmancy-option>
9
+ <schmancy-option value="de" label="Germany"></schmancy-option>
10
+ </schmancy-select>
11
+ ```
12
+
13
+ ## Properties
14
+ | Property | Type | Default | Description |
15
+ |----------|------|---------|-------------|
16
+ | value | string \| string[] | `''` | Selected value(s) |
17
+ | values | string[] | `[]` | Selected values (multi-select) |
18
+ | label | string | `''` | Label text |
19
+ | placeholder | string | `''` | Placeholder when no selection |
20
+ | name | string | `undefined` | Form submission name |
21
+ | required | boolean | `false` | Whether selection is required |
22
+ | disabled | boolean | `false` | Whether the select is disabled |
23
+ | multi | boolean | `false` | Enable multi-select mode |
24
+ | hint | string | `''` | Hint text below the select |
25
+ | size | `'xxs'\|'xs'\|'sm'\|'md'\|'lg'` | `'md'` | Input height |
26
+ | validateOn | `'always'\|'touched'\|'dirty'\|'submitted'` | `'touched'` | When to show validation |
27
+
28
+ ## Events
29
+ | Event | Detail | Description |
30
+ |-------|--------|-------------|
31
+ | change | `{ value: string \| string[] }` | When selection changes |
32
+
33
+ ## Examples
34
+ ```html
35
+ <!-- Multi-select -->
36
+ <schmancy-select label="Tags" multi placeholder="Select tags...">
37
+ <schmancy-option value="urgent" label="Urgent"></schmancy-option>
38
+ <schmancy-option value="review" label="Review"></schmancy-option>
39
+ <schmancy-option value="done" label="Done"></schmancy-option>
40
+ </schmancy-select>
41
+
42
+ <!-- Compact size -->
43
+ <schmancy-select size="xs" placeholder="Status">
44
+ <schmancy-option value="active" label="Active"></schmancy-option>
45
+ <schmancy-option value="inactive" label="Inactive"></schmancy-option>
46
+ </schmancy-select>
47
+ ```
48
+
49
+ Children must be `<schmancy-option>` elements with `value` and `label` attributes.
@@ -0,0 +1,76 @@
1
+ # schmancy-sheet / sheet
2
+
3
+ > Side/bottom panel with glass backdrop, luminous edge glow, and spring entry animation. Use `sheet` service for imperative usage.
4
+
5
+ ## Usage
6
+ ```typescript
7
+ import { sheet } from '@mhmo91/schmancy'
8
+
9
+ sheet.push({
10
+ component: MyComponent, // Component class or tag name
11
+ position: SchmancySheetPosition.Side,
12
+ props: { itemId: '123' }, // Passed to component
13
+ })
14
+ ```
15
+
16
+ ## sheet API
17
+ | Method | Description |
18
+ |--------|-------------|
19
+ | `push(config)` | Open a sheet with component content |
20
+ | `dismiss(uid?)` | Close sheet by uid, or most recent |
21
+ | `closeAll()` | Close all open sheets |
22
+ | `isOpen(uid)` | Check if sheet with uid is open |
23
+
24
+ ## SheetConfig
25
+ | Option | Type | Default | Description |
26
+ |--------|------|---------|-------------|
27
+ | `component` | `ComponentType` | required | Component class or lazy loader |
28
+ | `uid` | `string` | Auto-generated | Unique identifier for the sheet |
29
+ | `position` | `SchmancySheetPosition` | Auto (side on desktop, bottom on mobile) | `Side` or `Bottom` |
30
+ | `persist` | `boolean` | `false` | Keep DOM after close |
31
+ | `lock` | `boolean` | `false` | Prevent ESC and overlay click dismiss |
32
+ | `props` | `Record<string, unknown>` | `undefined` | Properties passed to component |
33
+ | `close` | `() => void` | `undefined` | Close callback |
34
+
35
+ ## Component Properties (schmancy-sheet)
36
+ | Property | Type | Default | Description |
37
+ |----------|------|---------|-------------|
38
+ | `open` | `boolean` | `false` | Open state |
39
+ | `position` | `'side' \| 'bottom'` | `'side'` | Panel position |
40
+ | `persist` | `boolean` | `false` | Keep in DOM after close |
41
+ | `lock` | `boolean` | `false` | Disable dismiss via ESC/overlay |
42
+ | `handleHistory` | `boolean` | `true` | Handle browser back button |
43
+
44
+ ## Events
45
+ | Event | Description |
46
+ |-------|-------------|
47
+ | `close` | Fired when sheet closes |
48
+
49
+ ## Physics
50
+ - Glass backdrop: `backdrop-blur-lg` + `backdrop-saturate-150`
51
+ - Luminous edge glow on panel (primary color, 15% intensity)
52
+ - Spring entry: `scale(0.95)` to `scale(1)` with Blackbird easing
53
+ - Side: slides from right; Bottom: slides from bottom
54
+ - Background siblings set to `inert` while open
55
+ - Stacks with dialogs via shared `overlayStack` z-index manager
56
+
57
+ ## Examples
58
+ ```typescript
59
+ import { sheet, SchmancySheetPosition } from '@mhmo91/schmancy'
60
+
61
+ // Open side sheet
62
+ sheet.push({
63
+ component: UserEditor,
64
+ props: { userId: '456' },
65
+ })
66
+
67
+ // Locked bottom sheet
68
+ sheet.push({
69
+ component: PaymentForm,
70
+ position: SchmancySheetPosition.Bottom,
71
+ lock: true,
72
+ })
73
+
74
+ // Dismiss programmatically
75
+ sheet.dismiss()
76
+ ```
@@ -0,0 +1,43 @@
1
+ # schmancy-slider / schmancy-slide
2
+
3
+ > Horizontal snap-scrolling carousel with optional arrow controls.
4
+
5
+ ## Usage
6
+ ```html
7
+ <schmancy-slider show-arrows>
8
+ <schmancy-slide>
9
+ <img src="a.jpg" />
10
+ </schmancy-slide>
11
+ <schmancy-slide>
12
+ <div class="p-8">Second slide</div>
13
+ </schmancy-slide>
14
+ <schmancy-slide>
15
+ <div class="p-8">Third slide</div>
16
+ </schmancy-slide>
17
+ </schmancy-slider>
18
+ ```
19
+
20
+ ## schmancy-slider Properties
21
+ | Property | Type | Default | Description |
22
+ |----------|------|---------|-------------|
23
+ | `showArrows` | boolean | `true` | Render prev/next navigation buttons |
24
+
25
+ ## Events
26
+ | Event | Payload | When |
27
+ |-------|---------|------|
28
+ | `slide-changed` | `{ index: number }` | Centered slide changes after scroll settles |
29
+
30
+ ## Behavior
31
+ - Each `schmancy-slide` is sized to `flex: 0 0 100%` of the slider.
32
+ - `scroll-snap-type: x mandatory` — scroll always lands on a slide.
33
+ - Scrollbars hidden across browsers.
34
+ - Scroll events throttled to 100ms for stable index tracking.
35
+ - Arrow buttons scroll to previous/next slide when `show-arrows` is true.
36
+
37
+ ## Example — programmatic control
38
+ ```typescript
39
+ const slider = this.renderRoot.querySelector('schmancy-slider')
40
+ slider?.addEventListener('slide-changed', (e: CustomEvent<{ index: number }>) => {
41
+ this.activeIndex = e.detail.index
42
+ })
43
+ ```