@motifx-community/ui 0.1.0-beta.0 → 0.1.0-beta.2

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 (165) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/README.md +16 -10
  3. package/dist/components/calendar/Calendar.d.ts +12 -0
  4. package/dist/components/calendar/calendar-props.d.ts +5 -0
  5. package/dist/components/daterangebox/DateRangeBox.d.ts +121 -0
  6. package/dist/components/daterangebox/date-range-box-props.d.ts +35 -0
  7. package/dist/components/daterangebox/date-range-preset.d.ts +6 -0
  8. package/dist/components/daterangebox/date-range.d.ts +2 -0
  9. package/dist/components/daterangebox/index.d.ts +4 -0
  10. package/dist/components/dropdown/DropDown.d.ts +14 -0
  11. package/dist/components/dropdown/drop-down-props.d.ts +5 -0
  12. package/dist/components/fileuploader/FileUploader.d.ts +133 -0
  13. package/dist/components/fileuploader/file-uploader-props.d.ts +46 -0
  14. package/dist/components/fileuploader/files-added-event-args.d.ts +9 -0
  15. package/dist/components/fileuploader/index.d.ts +7 -0
  16. package/dist/components/fileuploader/upload-event-args.d.ts +10 -0
  17. package/dist/components/fileuploader/upload-item.d.ts +12 -0
  18. package/dist/components/fileuploader/upload-mode.d.ts +2 -0
  19. package/dist/components/fileuploader/upload-status.d.ts +2 -0
  20. package/dist/components/loadpanel/LoadPanel.d.ts +70 -0
  21. package/dist/components/loadpanel/index.d.ts +3 -0
  22. package/dist/components/loadpanel/load-panel-props.d.ts +29 -0
  23. package/dist/components/loadpanel/load-panel-target.d.ts +3 -0
  24. package/dist/components/popover/Popover.d.ts +98 -0
  25. package/dist/components/popover/index.d.ts +5 -0
  26. package/dist/components/popover/popover-close-reason.d.ts +2 -0
  27. package/dist/components/popover/popover-closing-event-args.d.ts +8 -0
  28. package/dist/components/popover/popover-props.d.ts +39 -0
  29. package/dist/components/popover/popover-show-on.d.ts +2 -0
  30. package/dist/components/scheduler/view/AgendaView.d.ts +1 -1
  31. package/dist/components/scrollview/ScrollView.d.ts +109 -0
  32. package/dist/components/scrollview/index.d.ts +7 -0
  33. package/dist/components/scrollview/pull-down-event-args.d.ts +9 -0
  34. package/dist/components/scrollview/reach-bottom-event-args.d.ts +9 -0
  35. package/dist/components/scrollview/scroll-event-args.d.ts +7 -0
  36. package/dist/components/scrollview/scroll-view-bars.d.ts +2 -0
  37. package/dist/components/scrollview/scroll-view-direction.d.ts +2 -0
  38. package/dist/components/scrollview/scroll-view-props.d.ts +31 -0
  39. package/dist/components/sortable/Sortable.d.ts +106 -0
  40. package/dist/components/sortable/index.d.ts +5 -0
  41. package/dist/components/sortable/sortable-drag-event-args.d.ts +15 -0
  42. package/dist/components/sortable/sortable-drop-event-args.d.ts +11 -0
  43. package/dist/components/sortable/sortable-orientation.d.ts +2 -0
  44. package/dist/components/sortable/sortable-props.d.ts +34 -0
  45. package/dist/components/stepper/Stepper.d.ts +121 -0
  46. package/dist/components/stepper/Wizard.d.ts +112 -0
  47. package/dist/components/stepper/WizardStep.d.ts +44 -0
  48. package/dist/components/stepper/index.d.ts +13 -0
  49. package/dist/components/stepper/step-changed-event-args.d.ts +11 -0
  50. package/dist/components/stepper/step-changing-event-args.d.ts +18 -0
  51. package/dist/components/stepper/stepper-item.d.ts +20 -0
  52. package/dist/components/stepper/stepper-label-position.d.ts +2 -0
  53. package/dist/components/stepper/stepper-orientation.d.ts +1 -0
  54. package/dist/components/stepper/stepper-props.d.ts +32 -0
  55. package/dist/components/stepper/stepper-status.d.ts +2 -0
  56. package/dist/components/stepper/wizard-finishing-event-args.d.ts +7 -0
  57. package/dist/components/stepper/wizard-props.d.ts +48 -0
  58. package/dist/components/stepper/wizard-step-props.d.ts +32 -0
  59. package/dist/core/flow-home.d.ts +6 -0
  60. package/dist/core/fold-text.d.ts +6 -0
  61. package/dist/core/ui-locale.d.ts +0 -2
  62. package/dist/core/ui-strings.d.ts +43 -0
  63. package/dist/generated/tokens.d.ts +1186 -11
  64. package/dist/index.d.ts +8 -1
  65. package/dist/index.js +22542 -20143
  66. package/dist/index.js.map +1 -1
  67. package/dist/locales/en.json +39 -1
  68. package/dist/locales/tr.json +39 -1
  69. package/dist/parts/data/DataItems.d.ts +5 -0
  70. package/dist/parts/data/KeyedItems.d.ts +2 -0
  71. package/dist/styles.css +1912 -8
  72. package/dist/tokens/index.d.ts +1186 -11
  73. package/dist/tokens/index.js +1186 -11
  74. package/dist/tokens/index.js.map +1 -1
  75. package/dist/tr-B218zMtu.js +1191 -0
  76. package/dist/tr-B218zMtu.js.map +1 -0
  77. package/docs/accordion.md +1 -1
  78. package/docs/actionsheet.md +1 -1
  79. package/docs/avatar.md +1 -1
  80. package/docs/badge.md +1 -1
  81. package/docs/bottomsheet.md +3 -3
  82. package/docs/breadcrumb.md +2 -2
  83. package/docs/button.md +3 -3
  84. package/docs/buttongroup.md +1 -1
  85. package/docs/calendar.md +1 -1
  86. package/docs/card.md +1 -1
  87. package/docs/checkbox.md +3 -3
  88. package/docs/chip.md +1 -1
  89. package/docs/colorbox.md +1 -1
  90. package/docs/combobox.md +1 -1
  91. package/docs/control.md +1 -1
  92. package/docs/datagrid-api.md +3 -3
  93. package/docs/datagrid-bands.md +1 -1
  94. package/docs/datagrid-drag-select.md +1 -1
  95. package/docs/datagrid-drag.md +1 -1
  96. package/docs/datagrid-editing.md +1 -1
  97. package/docs/datagrid-filtering.md +1 -1
  98. package/docs/datagrid-forms.md +1 -1
  99. package/docs/datagrid-grouping.md +1 -1
  100. package/docs/datagrid-layout.md +1 -1
  101. package/docs/datagrid-lookups.md +1 -1
  102. package/docs/datagrid-master-detail.md +1 -1
  103. package/docs/datagrid-scrolling.md +1 -1
  104. package/docs/datagrid-selection.md +1 -1
  105. package/docs/datagrid.md +1 -1
  106. package/docs/datebox.md +3 -3
  107. package/docs/daterangebox.md +192 -0
  108. package/docs/drawer.md +1 -1
  109. package/docs/dropdown.md +13 -7
  110. package/docs/fileuploader.md +201 -0
  111. package/docs/filterbuilder.md +3 -3
  112. package/docs/formlayout.md +1 -1
  113. package/docs/home.md +1 -1
  114. package/docs/keyboard.md +1 -1
  115. package/docs/language.md +229 -0
  116. package/docs/layout.md +3 -3
  117. package/docs/listbox.md +3 -3
  118. package/docs/loadpanel.md +184 -0
  119. package/docs/lookup.md +86 -2
  120. package/docs/menus.md +1 -1
  121. package/docs/numberbox.md +3 -3
  122. package/docs/pagination.md +1 -1
  123. package/docs/popover.md +221 -0
  124. package/docs/progress.md +3 -3
  125. package/docs/radiogroup.md +1 -1
  126. package/docs/rating.md +1 -1
  127. package/docs/scheduler-agenda.md +1 -1
  128. package/docs/scheduler-big-data.md +1 -1
  129. package/docs/scheduler-editing.md +1 -1
  130. package/docs/scheduler-form.md +1 -1
  131. package/docs/scheduler-icalendar.md +1 -1
  132. package/docs/scheduler-mobile.md +1 -1
  133. package/docs/scheduler-recurrence.md +1 -1
  134. package/docs/scheduler-resources.md +1 -1
  135. package/docs/scheduler-timeline.md +1 -1
  136. package/docs/scheduler.md +1 -1
  137. package/docs/scrollview.md +185 -0
  138. package/docs/showcase.md +1 -1
  139. package/docs/skeleton.md +1 -1
  140. package/docs/slider.md +3 -3
  141. package/docs/sortable.md +213 -0
  142. package/docs/stepper.md +238 -0
  143. package/docs/switch.md +1 -1
  144. package/docs/tabdocs-dock.md +1 -1
  145. package/docs/tabdocs-drag.md +1 -1
  146. package/docs/tabdocs-menus.md +1 -1
  147. package/docs/tabdocs-mobile.md +1 -1
  148. package/docs/tabdocs-tabs.md +1 -1
  149. package/docs/tabdocs-windows.md +1 -1
  150. package/docs/tabdocs-workspace.md +1 -1
  151. package/docs/tabdocs.md +1 -1
  152. package/docs/tabs.md +3 -3
  153. package/docs/tagbox.md +3 -3
  154. package/docs/textarea.md +3 -3
  155. package/docs/textbox.md +3 -3
  156. package/docs/toast.md +3 -3
  157. package/docs/tokens.md +357 -122
  158. package/docs/toolbar.md +3 -3
  159. package/docs/tooltip.md +1 -1
  160. package/docs/treeview.md +3 -3
  161. package/docs/window.md +3 -3
  162. package/docs/wizard.md +240 -0
  163. package/llms-full.txt +2518 -245
  164. package/llms.txt +10 -1
  165. package/package.json +10 -4
@@ -0,0 +1,221 @@
1
+ # Popover
2
+
3
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
4
+
5
+ Content next to the element it belongs to: a title, a close button, a form, a card. It opens on a press or while the pointer rests on its target, follows it, and points at it with an arrow where the design language has one.
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { Popover } from '@motifx-community/ui';
11
+ ```
12
+
13
+ ## From JSX and from code
14
+
15
+ The JSX children are the content; `target` names the element or component it opens next to. From code, `content` gives the content and `open()`, `close()` and `toggle()` move it; `value` and `x-model` say whether it is open.
16
+
17
+ ```tsx
18
+ import { reactive } from '@motifx/core';
19
+ import { Button, Popover, Stack, TextBox } from '@motifx-community/ui';
20
+
21
+ /** A popover with a title, a close button and a small form; one made from code for a plain element. */
22
+ export default function Basic() {
23
+ const s = reactive({ open: false, name: 'Ada', saved: '' });
24
+ let button!: Button;
25
+ let link!: HTMLElement;
26
+ const coded = new Popover({ title: 'From code', content: new Button({ text: 'OK', variant: 'outline', onclick: () => coded.close() }) });
27
+
28
+ return (
29
+ <Stack orientation="horizontal" wrap align="center">
30
+ <Button ref={(b: Button) => (button = b)} text="Rename" variant="outline" />
31
+ <Popover target={() => button} title="New name" showClose x-model={() => s.open}>
32
+ <Stack orientation="horizontal" wrap align="center">
33
+ <TextBox label="Name" x-model={() => s.name} />
34
+ <Button text="Save" tone="accent" onclick={() => ((s.saved = s.name), (s.open = false))} />
35
+ </Stack>
36
+ </Popover>
37
+ <output class="po-saved">{() => (s.saved ? `Saved: ${s.saved}` : s.open ? 'Open' : 'Closed')}</output>
38
+ <a
39
+ href="#from-code"
40
+ class="po-link"
41
+ ref={(c: { element: HTMLElement }) => (link = c.element)}
42
+ onclick={(e: Event) => {
43
+ e.preventDefault();
44
+ coded.target = link;
45
+ coded.toggle();
46
+ }}
47
+ >
48
+ A popover from code
49
+ </a>
50
+ </Stack>
51
+ );
52
+ }
53
+ ```
54
+
55
+ ## While the pointer rests
56
+
57
+ `showOn: 'hover'` opens it after `delay` while the pointer rests on the target, and when the target has keyboard focus; the pointer may move onto the popover. It closes `hideDelay` after the pointer leaves both.
58
+
59
+ ```tsx
60
+ import { Avatar, Popover, Stack } from '@motifx-community/ui';
61
+
62
+ /** A card that opens while the pointer rests on a name, or when the name has keyboard focus. */
63
+ export default function Hover() {
64
+ let name!: HTMLElement;
65
+ return (
66
+ <Stack orientation="horizontal" wrap align="center">
67
+ <span>
68
+ Reviewed by{' '}
69
+ <a href="#ada" class="po-person" ref={(c: { element: HTMLElement }) => (name = c.element)} onclick={(e: Event) => e.preventDefault()}>
70
+ Ada Lovelace
71
+ </a>
72
+ </span>
73
+ <Popover target={() => name} showOn="hover" placement="top" label="Ada Lovelace">
74
+ <Stack orientation="horizontal" align="center">
75
+ <Avatar name="Ada Lovelace" size="lg" />
76
+ <Stack>
77
+ <strong>Ada Lovelace</strong>
78
+ <span>Analytical Engine, Programs</span>
79
+ </Stack>
80
+ </Stack>
81
+ </Popover>
82
+ </Stack>
83
+ );
84
+ }
85
+ ```
86
+
87
+ ## Placements, the arrow and a width
88
+
89
+ ```tsx
90
+ import { reactive } from '@motifx/core';
91
+ import { Button, CheckBox, Popover, Stack, type PopupPlacement } from '@motifx-community/ui';
92
+
93
+ const PLACEMENTS: PopupPlacement[] = ['top-start', 'top', 'top-end', 'start', 'end', 'bottom-start', 'bottom', 'bottom-end'];
94
+
95
+ /** Every placement; the arrow where the language draws one, and a width of its own. */
96
+ export default function Placements() {
97
+ const s = reactive({ arrow: true, placement: 'bottom' as PopupPlacement });
98
+ let button!: Button;
99
+ return (
100
+ <Stack gap="md">
101
+ <Stack orientation="horizontal" wrap align="center">
102
+ {PLACEMENTS.map(placement => (
103
+ <Button key={placement} text={placement} variant={() => (s.placement === placement ? 'solid' : 'outline')} size="sm" onclick={() => (s.placement = placement)} />
104
+ ))}
105
+ <CheckBox label="Arrow" x-model={() => s.arrow} />
106
+ </Stack>
107
+ <div style="display: flex; justify-content: center; padding: 3rem 0">
108
+ <Button ref={(b: Button) => (button = b)} text="Open" />
109
+ </div>
110
+ <Popover target={() => button} placement={() => s.placement} arrow={() => s.arrow} width="16rem" label="Placement">
111
+ <p>{() => `Placed at ${s.placement}; it moves to the other side when there is no room.`}</p>
112
+ </Popover>
113
+ </Stack>
114
+ );
115
+ }
116
+ ```
117
+
118
+ ## Keeping it open
119
+
120
+ ```tsx
121
+ import { reactive } from '@motifx/core';
122
+ import { Button, Popover, Stack, TextArea } from '@motifx-community/ui';
123
+
124
+ /** A press outside does not close it, and onClosing keeps it open while there is unsaved text; Escape and the button close it. */
125
+ export default function Events() {
126
+ const s = reactive({ note: '', told: '' });
127
+ let button!: Button;
128
+ let pop!: Popover;
129
+ return (
130
+ <Stack orientation="horizontal" wrap align="center">
131
+ <Button ref={(b: Button) => (button = b)} text="Add a note" variant="outline" />
132
+ <Popover
133
+ ref={(p: Popover) => (pop = p)}
134
+ target={() => button}
135
+ title="Note"
136
+ closeOnOutside={false}
137
+ onClosing={e => {
138
+ if (e.reason === 'escape' && s.note.trim() !== '') {
139
+ e.cancel = true;
140
+ s.told = 'Save or clear the note first.';
141
+ }
142
+ }}
143
+ onClosed={reason => (s.told = `Closed: ${String(reason)}`)}
144
+ >
145
+ <Stack gap="sm">
146
+ <TextArea label="Text" x-model={() => s.note} rows={3} />
147
+ <Button text="Save" tone="accent" onclick={() => ((s.note = ''), pop.close())} />
148
+ </Stack>
149
+ </Popover>
150
+ <output class="po-told">{() => s.told}</output>
151
+ </Stack>
152
+ );
153
+ }
154
+ ```
155
+
156
+ ## Behaviour
157
+
158
+ | Topic | How |
159
+ | --- | --- |
160
+ | `Opening` | By a press on the target, by the pointer resting on it (`hover`), or from code. It appears in the browser’s top layer, next to the target, and follows it while the page scrolls. |
161
+ | `Focus` | Opened by a press or from code, focus moves to the first focusable part inside, else to the popover; it goes back to the target when the popover closes. Opened by hover, focus stays where it is. |
162
+ | `Closing` | Escape, a press outside it and its target, focus leaving both (Tab out), the close button, the target pressed again, or the pointer leaving both (`hover`). `onClosing` may keep it open. |
163
+ | `Placement` | `placement` names the side and the alignment, as for the kit’s popups; without room on that side it opens on the other. |
164
+ | `Where it lives` | Made from code, it goes into the nearest container of its target that can hold it, so it stays in the target’s window and landmark. |
165
+
166
+ ## Accessibility
167
+
168
+ | Topic | How |
169
+ | --- | --- |
170
+ | `Role` | `dialog`, named by its title, else by `label`: give it one. |
171
+ | `Target` | `aria-controls` and `aria-expanded`; `aria-haspopup="dialog"` when a press opens it. |
172
+ | `Keyboard` | Tab moves through the content and out (which closes it); Escape closes and returns focus. A `hover` popover opens on keyboard focus too. |
173
+ | `Arrow` | Decorative. |
174
+
175
+ ## Styling
176
+
177
+ | Hook | What it is |
178
+ | --- | --- |
179
+ | `.mx-popover` | The popover. `data-side` (`top`, `bottom`, `start`, `end`), `data-arrow`. |
180
+ | `.mx-popover__arrow` | The arrow. |
181
+ | `.mx-popover__header, .mx-popover__title, .mx-popover__close` | The header, its title and the close button. |
182
+ | `.mx-popover__body` | The content. |
183
+
184
+ ### Component tokens
185
+
186
+ | Token | What it sets |
187
+ | --- | --- |
188
+ | `popover.surface, .arrow, .header, .title, .body` | Units: the surface (`focus`), the arrow (`display`, `size`, its fill and frame), the header, the title and the body. |
189
+ | `popover.close` | Place: the close button’s look (`variant`). |
190
+ | `popover.offset, .enter-offset, .header-gap` | The gap to the target, how far it comes in as it appears, the space between title and close button. |
191
+
192
+ ## API reference
193
+
194
+ ### Props
195
+
196
+ | Prop | Type | Default | Description |
197
+ | --- | --- | --- | --- |
198
+ | `target` | `Bind<Element \| ComponentBase \| null>` | `null` | The element or component it opens next to. |
199
+ | `title` | `Bind<string>` | `''` | A title in the header. The same property as `text`. |
200
+ | `label` | `Bind<string>` | `''` | What screen readers call it when it has no title. |
201
+ | `content` | `Bind<ComponentBase \| null>` | `null` | Content from code, after the JSX children. |
202
+ | `showOn` | `Bind<PopoverShowOn>` | `'click'` | `click`: a press on the target toggles it; `hover`: the pointer resting on the target, or keyboard focus on it; `manual`: only code. |
203
+ | `placement` | `Bind<PopupPlacement>` | `'bottom'` | The side and the alignment; it opens on the other side when there is no room. |
204
+ | `arrow` | `Bind<boolean>` | `true` | An arrow towards the target, where the design language draws one. |
205
+ | `showClose` | `Bind<boolean>` | `false` | A close button in the header. |
206
+ | `width` | `Bind<string \| number \| null>` | `null` | A width of its own (a CSS length, or pixels). |
207
+ | `closeOnOutside` | `Bind<boolean>` | `true` | A press outside it and its target closes it. |
208
+ | `delay, hideDelay` | `Bind<number>` | `300`, `200` | Milliseconds the pointer rests on the target before it opens, and it stays after the pointer leaves both (`showOn: 'hover'`). |
209
+ | `value` | `Bind<boolean>` | `false` | Open or not; `x-model` binds it two-way. |
210
+
211
+ ### Events, properties and methods
212
+
213
+ | Member | Kind | Description |
214
+ | --- | --- | --- |
215
+ | `onOpened` | event | It opened. |
216
+ | `onClosing` | event | About to close (`reason`); `cancel = true` keeps it open. |
217
+ | `onClosed` | event | It closed, with the reason: `escape`, `outside`, `focus`, `toggle`, `hover`, `close-button`, `code`. |
218
+ | `open(), close(reason?), toggle()` | `boolean` / `void` | From code; `open()` is `false` without a target on the page or when disabled. |
219
+ | `place()` | `void` | Lines it up with its target again, after its content changed size. |
220
+ | `isOpen` | read-only | Whether it is open now. |
221
+ | `closeButton, body` | read-only | The close button (the kit’s) and the part that holds the content. |
package/docs/progress.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ProgressBar and Spinner
2
2
 
3
- > Feedback · @motifx-community/ui 0.1.0-beta.0
3
+ > Feedback · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  ProgressBar shows how far some work is, as a line or a circle, or that it runs when that is not known. Spinner says "busy, wait": a turning ring, alone or over a panel while it loads, shown only after a delay so quick work does not flash it.
6
6
 
@@ -307,7 +307,7 @@ A bar or a spinner without a label is named `uiLocale.strings.loading`. The perc
307
307
 
308
308
  ```tsx
309
309
  import { reactive } from '@motifx/core';
310
- import { Button, enStrings, ProgressBar, trStrings, uiLocale } from '@motifx-community/ui';
310
+ import { Button, ProgressBar, uiLocale } from '@motifx-community/ui';
311
311
  import { kitTexts } from '../../../shared/kit-texts';
312
312
 
313
313
  /** Switches the name of unlabelled bars and spinners, and the language the percent is written in. */
@@ -315,7 +315,7 @@ export default function Localization() {
315
315
  const s = reactive({ lang: 'en' });
316
316
  const toggle = () => {
317
317
  s.lang = s.lang === 'en' ? 'tr' : 'en';
318
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
318
+ void uiLocale.use(s.lang);
319
319
  };
320
320
  return (
321
321
  <>
@@ -1,6 +1,6 @@
1
1
  # RadioGroup
2
2
 
3
- > Choice · @motifx-community/ui 0.1.0-beta.0
3
+ > Choice · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  A set of options of which one is chosen: from plain values, from your own objects or from a live list; one under the other, side by side or in columns; options that are disabled, hidden or carry a help line; one Tab stop and the arrow keys.
6
6
 
package/docs/rating.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rating
2
2
 
3
- > Editors · @motifx-community/ui 0.1.0-beta.0
3
+ > Editors · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  A row of stars to give a score or to show one, whole or by halves. It is a field: label, help text, rules and `x-model` work as in every field.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Agenda
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  The coming days as a list: each day with its appointments in time order, a day with none left out.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Big data
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  Thousands of resources and appointments: the scheduler builds only what is in view, and lays out only what changed.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Editing
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  Appointments are added, moved, resized, copied and deleted with the pointer, the keys and code; every change asks its event first, can wait for a server, and goes back when saving fails.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: The appointment form
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  The appointment form set up without events: which fields, in which order, in groups and tabs; editors of your own; checks per field; fields shown or locked for one appointment only. Or a form of your own.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: iCalendar and print
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  Appointments out to an iCalendar file and back in (RFC 5545), for Outlook, Google Calendar and Apple Calendar; and the scheduler on paper.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Tablet and phone
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  On a tablet and a phone the scheduler keeps its appointments, views and date and shows them another way: a phone gets the agenda, a compact bar and sheets from the bottom; a finger lifts, resizes, swipes and pinches.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Recurrence and time zones
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  Appointments that repeat by an RFC 5545 rule, with times left out and occurrences changed apart; a question on what a change reaches; an editor of the rule; and the days on the clock of any time zone, summer time included.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Resources and groups
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  Rooms, people and any other kind of resource: they colour the appointments, split the columns into groups (nested, or under each date), say when each one works and when nothing may be put in.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Scheduler: Timeline
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  A row per resource with the time running along it: a day, a week, a work week or a month. Appointments at the same time stack in their row, and the row grows to fit them.
6
6
 
package/docs/scheduler.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Scheduler
2
2
 
3
- > Scheduler · @motifx-community/ui 0.1.0-beta.0
3
+ > Scheduler · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  Appointments over days and hours: day, week, work week and month views, all-day and multi-day bars, appointments at the same time side by side, and "+N more" where a day is full. From an array or a data source, with every setting live.
6
6
 
@@ -0,0 +1,185 @@
1
+ # ScrollView
2
+
3
+ > Navigation · @motifx-community/ui 0.1.0-beta.2
4
+
5
+ Content that scrolls in a box of its own: the bars shown as told, a pull from the top that asks for what is new, a reach near the end that asks for more. Moved from code to a position or to an element.
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { ScrollView } from '@motifx-community/ui';
11
+ ```
12
+
13
+ ## A box that scrolls
14
+
15
+ The JSX children are the content. `showScrollbar` says when the bars show; `scrollTo` and `scrollToElement` move the content from code, `onScrolled` tells where it stands.
16
+
17
+ ```tsx
18
+ import { reactive } from '@motifx/core';
19
+ import { Button, ScrollView, Stack, type ScrollViewBars } from '@motifx-community/ui';
20
+
21
+ const LINES = Array.from({ length: 40 }, (_, i) => `Line ${i + 1} of a long text that needs a box of its own to scroll in.`);
22
+ const MODES: ScrollViewBars[] = ['onScroll', 'onHover', 'always', 'never'];
23
+
24
+ /** A box that scrolls, its bars shown as told; moved from code to a line and back to the top. */
25
+ export default function Bars() {
26
+ const s = reactive({ bars: 'onScroll' as ScrollViewBars, top: 0 });
27
+ let view!: ScrollView;
28
+ return (
29
+ <Stack gap="md" style="inline-size: 100%">
30
+ <Stack orientation="horizontal" wrap align="center">
31
+ {MODES.map(mode => (
32
+ <Button key={mode} text={mode} size="sm" variant={() => (s.bars === mode ? 'solid' : 'outline')} onclick={() => (s.bars = mode)} />
33
+ ))}
34
+ <Button text="Line 20" variant="outline" size="sm" onclick={() => view.scrollToElement(view.content.element.querySelectorAll('p')[19], true)} />
35
+ <Button text="Top" variant="outline" size="sm" onclick={() => view.scrollTo(0, true)} />
36
+ <output class="sv-top">{() => `scrollTop: ${Math.round(s.top)}`}</output>
37
+ </Stack>
38
+ <ScrollView ref={(v: ScrollView) => (view = v)} label="Long text" class="sv-text" showScrollbar={() => s.bars} style="block-size: 12rem" onScrolled={e => (s.top = e.top)}>
39
+ {LINES.map(line => (
40
+ <p key={line}>{line}</p>
41
+ ))}
42
+ </ScrollView>
43
+ </Stack>
44
+ );
45
+ }
46
+ ```
47
+
48
+ ## Pull to refresh
49
+
50
+ With `pullToRefresh`, the content pulled down from its top asks `onPullDown`. Set `promise` (or call `release()`) and the panel goes when the work is done.
51
+
52
+ ```tsx
53
+ import { reactive } from '@motifx/core';
54
+ import { Panel, ScrollView, Stack } from '@motifx-community/ui';
55
+
56
+ /** Pulled down from the top, the list asks for what is new and shows the panel until the promise settles. */
57
+ export default function Pull() {
58
+ const s = reactive({ notes: ['Welcome aboard', 'Your plan was renewed', 'A new comment on "Roadmap"'], count: 0 });
59
+ const reload = () =>
60
+ new Promise<void>(resolve =>
61
+ setTimeout(() => {
62
+ s.count++;
63
+ s.notes = [`Fresh note ${s.count}`, ...s.notes];
64
+ resolve();
65
+ }, 1200)
66
+ );
67
+ return (
68
+ <Stack gap="sm" style="inline-size: 100%">
69
+ <span>Drag the list down from its top (a finger, or the mouse) and let go.</span>
70
+ <ScrollView label="Notes" class="sv-notes" pullToRefresh onPullDown={e => (e.promise = reload())} style="block-size: 12rem">
71
+ {s.notes.map(note => (
72
+ <Panel key={note} variant="outline" padding="sm">
73
+ {note}
74
+ </Panel>
75
+ ))}
76
+ </ScrollView>
77
+ </Stack>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ## Load more near the end
83
+
84
+ With `loadOnReachBottom`, a scroll within `reachBottomOffset` of the end asks `onReachBottom` once; `release()` lets the next reach ask again, `release(true)` says there is no more. Content that does not fill the box asks at once.
85
+
86
+ ```tsx
87
+ import { reactive } from '@motifx/core';
88
+ import { Panel, ScrollView, Stack } from '@motifx-community/ui';
89
+
90
+ const TOTAL = 60;
91
+ const PAGE = 15;
92
+
93
+ // A page of rows, as a server would send them.
94
+ const fetchRows = (from: number) =>
95
+ new Promise<string[]>(resolve => setTimeout(() => resolve(Array.from({ length: Math.min(PAGE, TOTAL - from) }, (_, i) => `Order #${1000 + from + i}`)), 800));
96
+
97
+ /** Near the end the view asks for more; the indicator stays until the rows are in, and `release(true)` ends it for good when there is no more. */
98
+ export default function More() {
99
+ const s = reactive({ rows: [] as string[] });
100
+ const more = () =>
101
+ fetchRows(s.rows.length).then(rows => {
102
+ s.rows = [...s.rows, ...rows];
103
+ return s.rows.length >= TOTAL;
104
+ });
105
+ return (
106
+ <Stack gap="sm" style="inline-size: 100%">
107
+ <output class="sv-more-told">{() => (s.rows.length >= TOTAL ? `All ${TOTAL} orders are in.` : `${s.rows.length} of ${TOTAL} orders`)}</output>
108
+ <ScrollView label="Orders" class="sv-orders" loadOnReachBottom reachBottomOffset={80} onReachBottom={e => more().then(done => e.release(done))} style="block-size: 14rem">
109
+ {s.rows.map(row => (
110
+ <Panel key={row} variant="outline" padding="sm">
111
+ {row}
112
+ </Panel>
113
+ ))}
114
+ </ScrollView>
115
+ </Stack>
116
+ );
117
+ }
118
+ ```
119
+
120
+ ## Behaviour
121
+
122
+ | Topic | How |
123
+ | --- | --- |
124
+ | `Scrolling` | The box scrolls with the wheel, the keys when focused, a finger, and from code. `direction` locks the other axis; the page behind does not scroll on when the content ends. |
125
+ | `Scrollbars` | The design system’s bars. With `onScroll` the thumb shows while the content moves and goes a moment after; with `onHover` while the pointer is over the view or focus is in it; `always` leaves them; `never` hides them, the content still scrolls. |
126
+ | `Pull to refresh` | From the top, with a finger or the pointer: the content comes down (harder the farther it goes) and the panel above it says to pull, then to release. Let go far enough it refreshes: the spinner turns until `release()` or the promise. A short pull goes back. |
127
+ | `Load more` | Within `reachBottomOffset` of the end, `onReachBottom` is asked once; the panel under the content shows meanwhile. Released, the next reach asks again, until `release(true)`. Content that does not fill the box asks at once, and again as it grows. |
128
+ | `Texts` | The kit’s, in the kit language, unless the text props say otherwise. |
129
+
130
+ ## Accessibility
131
+
132
+ | Topic | How |
133
+ | --- | --- |
134
+ | `Region` | A focusable box named by `label`; the arrow keys, Page Up/Down, Home and End scroll it as the browser does. |
135
+ | `Panels` | Live regions: “Refreshing…” and “Loading…” are read when they appear. |
136
+ | `Spinners` | Decorative; the texts say what is going on. |
137
+ | `Motion` | A finger that pulls does not scroll the page; a finger that scrolls does not pull. |
138
+
139
+ ## Styling
140
+
141
+ | Hook | What it is |
142
+ | --- | --- |
143
+ | `.mx-scroll-view` | The box. `data-direction`, `data-bars`, `data-scrolling` while the content moves, `data-pull` when pulling is on, `data-pulling` during a pull, `data-pull-state` (`pull`, `release`, `refreshing`), `data-loading`. |
144
+ | `.mx-scroll-view__content` | What holds the children; it moves down during a pull. |
145
+ | `.mx-scroll-view__pull, .mx-scroll-view__pull-text, .mx-scroll-view__pull-spinner` | The panel above the content, its text and the kit’s spinner. |
146
+ | `.mx-scroll-view__bottom, .mx-scroll-view__bottom-text, .mx-scroll-view__bottom-spinner` | The panel under the content while more loads. |
147
+
148
+ ### Component tokens
149
+
150
+ | Token | What it sets |
151
+ | --- | --- |
152
+ | `scroll-view.box` | Unit: the box (`focus`). |
153
+ | `scroll-view.pull, .pull-text, .bottom, .bottom-text` | Units: the two panels (the pull one `release` and `refreshing`) and their texts. |
154
+ | `scroll-view.panel-height, .panel-gap` | The panels’ height; the space between a panel’s spinner and its text. |
155
+
156
+ ## API reference
157
+
158
+ ### Props
159
+
160
+ | Prop | Type | Default | Description |
161
+ | --- | --- | --- | --- |
162
+ | `direction` | `Bind<ScrollViewDirection>` | `'vertical'` | `vertical`, `horizontal` or `both`: which way the content scrolls. |
163
+ | `showScrollbar` | `Bind<ScrollViewBars>` | `'onScroll'` | When the bars show: `onScroll` while scrolling, `onHover` while the pointer is over the view, `always`, `never`. |
164
+ | `pullToRefresh` | `Bind<boolean>` | `false` | Pulling the content down from its top asks `onPullDown` for what is new. |
165
+ | `loadOnReachBottom` | `Bind<boolean>` | `false` | Scrolling near the end asks `onReachBottom` for more; so does content that does not reach the end. |
166
+ | `reachBottomOffset` | `Bind<number>` | `100` | Pixels before the end at which `onReachBottom` is asked. |
167
+ | `pullDownText, releaseText, refreshingText` | `Bind<string>` | the kit’s texts | The pull panel’s texts: while pulling, once far enough, while refreshing. |
168
+ | `reachBottomText` | `Bind<string>` | the kit’s “Loading…” | The text under the content while more loads. |
169
+ | `label` | `Bind<string>` | `''` | What screen readers call the scrolling region. |
170
+
171
+ ### Events, properties and methods
172
+
173
+ | Member | Kind | Description |
174
+ | --- | --- | --- |
175
+ | `onPullDown` | event | The content was pulled down and let go. Load what is new, then `release()`, or set `promise` and the panel goes when it settles. |
176
+ | `onReachBottom` | event | The content was scrolled near its end. Load more, then `release()`; `release(true)` says there is no more and the view stops asking. A `promise` releases too. |
177
+ | `onScrolled` | event | The position changed: `top`, `left`. |
178
+ | `scrollTo(where, smooth?)` | `void` | To a top, or `{ top, left }`; `smooth` animates. |
179
+ | `scrollBy({ top, left }, smooth?)` | `void` | By a distance. |
180
+ | `scrollToElement(target, smooth?)` | `void` | Brings an element (or a component) of the content into view. |
181
+ | `refresh(), release()` | `void` | Starts a refresh as a pull would; ends it. |
182
+ | `loadMore(), update()` | `boolean` / `void` | Asks for more now; looks at the position again after the content changed. |
183
+ | `scrollTop, scrollLeft` | read-only | Where the content stands. |
184
+ | `isRefreshing, isLoading` | read-only | A refresh or a loading is going on. |
185
+ | `content` | read-only | The element that holds the children, between the two panels. |
package/docs/showcase.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Showcase: an order screen
2
2
 
3
- > Get started · @motifx-community/ui 0.1.0-beta.0
3
+ > Get started · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  An order screen built with the kit, the way a MotifJS app is built: the state and the operations live in a model (`OrderModel`), the page binds to it. The customer list is a data source of 5,000 rows that answers like a server.
package/docs/skeleton.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Skeleton
2
2
 
3
- > Display · @motifx-community/ui 0.1.0-beta.0
3
+ > Display · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  The shape of what is loading, so the page keeps its layout while data arrives. Given content, it shows the content in the same place once loading ends.
6
6
 
package/docs/slider.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Slider
2
2
 
3
- > Editors · @motifx-community/ui 0.1.0-beta.0
3
+ > Editors · @motifx-community/ui 0.1.0-beta.2
4
4
 
5
5
  A value picked on a track by dragging a thumb or with the keys: one number, or a range with two thumbs. Steps, marks with labels, a value bubble, a vertical form and number formatting, with the label, help line and validation every field has.
6
6
 
@@ -247,7 +247,7 @@ The names of the two thumbs of a range come from `uiLocale.strings` (`minimum`,
247
247
 
248
248
  ```tsx
249
249
  import { reactive } from '@motifx/core';
250
- import { Button, enStrings, Slider, trStrings, uiLocale } from '@motifx-community/ui';
250
+ import { Button, Slider, uiLocale } from '@motifx-community/ui';
251
251
  import { kitTexts } from '../../../shared/kit-texts';
252
252
 
253
253
  /** Switches the names of the thumbs; the price slider writes its numbers in the chosen language. */
@@ -255,7 +255,7 @@ export default function Localization() {
255
255
  const s = reactive({ lang: 'en' });
256
256
  const toggle = () => {
257
257
  s.lang = s.lang === 'en' ? 'tr' : 'en';
258
- uiLocale.strings = s.lang === 'en' ? enStrings : trStrings;
258
+ void uiLocale.use(s.lang);
259
259
  };
260
260
  return (
261
261
  <>