@apliteni/apliteni-ui 0.132.0 → 0.136.0

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.
@@ -6,13 +6,13 @@
6
6
 
7
7
  **Rule:** At rest, a file drop is one row: the button that opens the picker and the accepted types beside it.
8
8
 
9
- **Why:** A tall box holds the page's best space open for a file that arrives once a month.
9
+ **Why:** A tall box holds the page's best space for a file that arrives once a month.
10
10
 
11
11
  **Do:** Put an Upload button and “PDF or CSV, up to 10 MB” on one line above the list they feed.
12
12
 
13
13
  **Don't:** Draw a tall dashed box with a glyph, an invitation and a button stacked inside it.
14
14
 
15
- **Except:** A page whose whole purpose is receiving one file may use the field-sized picker, which carries a label of its own.
15
+ **Except:** A page that exists to receive one file may use the field-sized picker, which has its own label. An empty page may show a dashed drop area until the first file arrives. See #458 for this exception.
16
16
 
17
17
  ## Paint the target only while a file is over it
18
18
 
@@ -26,15 +26,17 @@
26
26
 
27
27
  **Don't:** Cover the whole window when one panel accepts the file.
28
28
 
29
+ **Except:** A page that takes files anywhere may cover the whole page, slightly transparent and blurred over a table. See #458 for this exception.
30
+
29
31
  ## Keep the file in the row it arrived in
30
32
 
31
33
  <!-- rule: in-the-row -->
32
34
 
33
35
  **Rule:** After the drop, the file's name, size and progress take the place the button was in, with remove on the name's line.
34
36
 
35
- **Why:** A row that changes in place keeps the page still while the file uploads.
37
+ **Why:** A row that changes in place keeps the page still during the upload.
36
38
 
37
- **Do:** Give the name a line with remove at its end, put the size under it, and run the progress track the full width below both.
39
+ **Do:** Put remove at the end of the name's line, the size under it, and the progress track below both.
38
40
 
39
41
  **Don't:** Push the list down with a progress card, or open a dialog over the page.
40
42
 
@@ -44,7 +46,7 @@
44
46
 
45
47
  **Rule:** A refused file keeps its place, says what it did wrong under its name, and offers Retry beside Remove.
46
48
 
47
- **Why:** A row that drops the file sends the reader back to choosing one. The reason is the one string here that has to be read in full, so it gets a line rather than a share of one.
49
+ **Why:** A row that drops the file sends the reader back to choosing one.
48
50
 
49
51
  **Do:** Keep the name on its line and say “Larger than 10 MB” under it, with Retry.
50
52
 
@@ -80,8 +82,8 @@
80
82
 
81
83
  **Rule:** Use a row where the file joins a list on the page, a region when one panel owns the file, and a dialog only when the upload needs answers of its own.
82
84
 
83
- **Why:** A dialog that asks nothing is one more thing to dismiss. The rule picks between three containers, so a drawing would show one of them and not the choice.
85
+ **Why:** A dialog that asks nothing is one more thing to dismiss. A drawing would show one container, not the choice.
84
86
 
85
- **Do:** Take a statement into the row under the statements it joins, and a replacement logo into the panel that shows it.
87
+ **Do:** Take a statement into the row under the statements it joins.
86
88
 
87
89
  **Don't:** Open a dialog for one file that the row behind it could have taken.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.132.0",
3
+ "version": "0.136.0",
4
4
 
5
5
  "workspaces": [
6
6
  "react"
package/react/README.md CHANGED
@@ -32,7 +32,10 @@ import { DataTable, Modal, Button } from '@apliteni/apliteni-ui/react';
32
32
  Both stylesheets. The React one adds what React's own components need — it carries no tokens, no
33
33
  reset and none of the kit's control CSS, so it cannot stand in for the first import.
34
34
 
35
- Components: `Success`, `SuccessPanel`, `SuccessCheck`, `Checkbox`, `Switch`, `SearchField`, `EmptyState`, `DataTable`, `Pagination`, `StatBand`, `Chart`, `Modal`, `Confirm`, `Drawer`, `CommandPalette`, `Dropdown`, `BackLink`, `Tooltip`, `Snippet`, `Segmented`, `Tabs`, `Button`, `Badge`, `Pill`, `StatusDot`, `Card`, `Callout`, `Icon`.
35
+ Components: `Success`, `SuccessPanel`, `SuccessCheck`, `Checkbox`, `Switch`, `SearchField`, `EmptyState`, `DataTable`, `Pagination`, `StatBand`, `Chart`, `Modal`, `Confirm`, `Feedback`, `Drawer`, `CommandPalette`, `Dropdown`, `BackLink`, `Tooltip`, `Snippet`, `Segmented`, `Tabs`, `Button`, `Badge`, `Pill`, `StatusDot`, `Card`, `Callout`, `Icon`.
36
+
37
+ `Card` accepts `title`, `sub`, children, `level`, `variant`, `pad`, `icon`, `href`, and `className`. `variant` is `accent` or `live`; omit it for the default surface. `pad` is `sm` or `lg`. A title is a heading unless `href` makes the whole card a link. Compose setting rows with `ui-card__row` and kit controls.
38
+ Three-option setting rows use `ui-card__row--tight-choice` to narrow pills below 360 px and stay on one line, while other rows keep full tap width.
36
39
 
37
40
  `Segmented` is a controlled choice toolbar: pass `options`, `value`, `onChange`,
38
41
  and a `label` for its accessible name. `size="sm"` compacts it, `block` makes it
@@ -447,6 +450,30 @@ and described by its body. Modal also accepts
447
450
  `initialFocusRef` for a mounted, focusable element inside its panel. Without it, Modal
448
451
  uses its normal opening focus.
449
452
 
453
+ ## Feedback
454
+
455
+ `Feedback` lets a reader select a passage and send a note about it. Pass `container`, a ref to
456
+ the element whose text can be selected, and `onSend`. A "Give feedback" pill appears above a
457
+ selection of `minChars` (3) or more. The pill opens a form with a chip for the nearest heading,
458
+ the quoted passage, a note field, Cancel and Send. The quoted passage stays highlighted until the
459
+ form closes. The container may mount after `Feedback`. On close, focus returns to the visible
460
+ control that had it before opening. If that control is gone, hidden, or disabled, focus returns to the pill.
461
+
462
+ ```tsx
463
+ <Feedback container={articleRef}
464
+ onSend={async ({ note, excerpt, anchor }) => ({ ok: await file(note, excerpt, anchor) })} />
465
+ ```
466
+
467
+ `onSend` receives `note`, `excerpt`, `anchor`, `sectionLabel` and `sectionTitle`. Resolve
468
+ `{ ok: true }` when the note is filed. Resolve `{ ok: false, error }`, or throw, to keep the form
469
+ open with the note intact and the error shown in place. `section` reshapes the chip and the
470
+ payload from the heading. Send stays off until the note has text and shows progress while the
471
+ request runs.
472
+
473
+ A sent note shows one line, `sentMessage`, and a Close button. Cancel, Escape, the close button
474
+ and the scrim dismiss the form without sending. `Feedback` uses the shared dialog stack and the
475
+ kit's buttons.
476
+
450
477
  ## Timeline
451
478
 
452
479
  `Timeline` displays a record’s events in the order provided. Pass events from oldest
@@ -817,6 +844,24 @@ the trigger's trailing edge. Without `ariaLabel` the trigger's own text is its a
817
844
  name, so a control reading "17 September 2026" is heard as that rather than as its
818
845
  placeholder. The popover stays mounted while closed, and is `inert` while it is.
819
846
 
847
+ ## Footer
848
+
849
+ `Footer` draws the kit's `full`, `slim` and `app` versions. The full version takes
850
+ brand text, a tagline, social links and link columns. The columns sit side by side
851
+ on an iPad or desktop and stack on a phone. Supply legal text and links for every
852
+ version. Pass `AccentPicker` and `ThemeToggle` through `switcher` when needed.
853
+
854
+ ```tsx
855
+ <Footer variant="full" tagline="A short product line"
856
+ columns={[{ title: 'Product', links: [{ label: 'Overview', href: '/overview' }] }]}
857
+ legal="© 2026 Example" switcher={<ThemeToggle />} />
858
+ ```
859
+
860
+ Use `brand` to replace the lockup with React content. Set `brand={false}` to hide
861
+ the brand block. Use `links` for React link columns in place of `columns`.
862
+ Use `legal` for text or React content. The component uses the kit's footer classes
863
+ and stylesheet.
864
+
820
865
  ## AccentPicker
821
866
 
822
867
  `AccentPicker` is a controlled group of the kit’s four accent swatches. Pass `value`
@@ -847,6 +847,43 @@
847
847
  .ui-drop.is-disabled .ui-drop__name {
848
848
  color: var(--disabled-ink);
849
849
  }
850
+ .ui-drop--area {
851
+ border: 1px dashed var(--border-strong);
852
+ border-radius: var(--radius-lg);
853
+ padding: var(--space-4);
854
+ }
855
+ .ui-drop--area.is-dragging {
856
+ border-color: var(--accent);
857
+ }
858
+ @media (max-width: 560px) {
859
+ .ui-drop--area {
860
+ padding: var(--space-3);
861
+ }
862
+ }
863
+ .ui-drop--page {
864
+ position: fixed;
865
+ inset: calc(var(--ui-app-band, 0px) + var(--ui-app-top, 0px) + var(--space-4)) var(--space-4) var(--space-4);
866
+ z-index: var(--z-overlay);
867
+ display: flex;
868
+ align-items: center;
869
+ justify-content: center;
870
+ pointer-events: none;
871
+ background: var(--bg);
872
+ }
873
+ @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
874
+ .ui-drop--page {
875
+ background: color-mix(in srgb, var(--bg) 80%, transparent);
876
+ -webkit-backdrop-filter: blur(var(--space-2));
877
+ backdrop-filter: blur(var(--space-2));
878
+ }
879
+ }
880
+ @media (prefers-reduced-transparency: reduce) {
881
+ .ui-drop--page {
882
+ background: var(--bg);
883
+ -webkit-backdrop-filter: none;
884
+ backdrop-filter: none;
885
+ }
886
+ }
850
887
 
851
888
  /* src/Toast.css */
852
889
  .rx-toast-stack {
@@ -907,6 +944,9 @@
907
944
  gap: var(--space-1);
908
945
  padding-inline: var(--space-2);
909
946
  }
947
+ .ui-react-app .ui-app__bar:not(:has(> .ui-app__menu:first-child)) {
948
+ padding-inline-start: var(--space-4);
949
+ }
910
950
  .ui-react-app .ui-app__bar-gap {
911
951
  display: none;
912
952
  }
@@ -96,13 +96,22 @@ declare const StatusDot: react.ForwardRefExoticComponent<Omit<HTMLAttributes<HTM
96
96
  } & react.RefAttributes<HTMLSpanElement>>;
97
97
 
98
98
  type Level = 2 | 3 | 4 | 5 | 6;
99
- declare function Card({ title, sub, level, className, children }: {
99
+ type CardProps = {
100
100
  title?: ReactNode;
101
101
  sub?: ReactNode;
102
102
  level?: Level;
103
+ /** `accent` tints the card with the accent and `live` with green. */
104
+ variant?: 'accent' | 'live';
105
+ /** `sm` trims the vertical padding. `lg` is the centred landing card. */
106
+ pad?: 'sm' | 'lg';
107
+ /** Glyph name for the chip before the title. Needs a `title`. */
108
+ icon?: string;
109
+ /** Makes the whole card a link. Its title is then a plain block, because a link holds no heading. */
110
+ href?: string;
103
111
  className?: string;
104
112
  children?: ReactNode;
105
- }): react.JSX.Element;
113
+ };
114
+ declare function Card({ title, sub, level, variant, pad, icon, href, className, children }: CardProps): react.JSX.Element;
106
115
 
107
116
  type CalloutVariant = 'neutral' | 'info' | 'success' | 'warn' | 'danger';
108
117
  interface CalloutProps {
@@ -156,6 +165,38 @@ type ConfirmProps = {
156
165
  };
157
166
  declare function Confirm({ open, title, body, confirmLabel, cancelLabel, danger, busy, onConfirm, onCancel, }: ConfirmProps): react.JSX.Element;
158
167
 
168
+ type FeedbackPayload = {
169
+ note: string;
170
+ excerpt: string;
171
+ anchor: string;
172
+ sectionLabel: string;
173
+ sectionTitle: string;
174
+ };
175
+ type FeedbackResult = {
176
+ ok: boolean;
177
+ error?: string;
178
+ };
179
+ type FeedbackSection = {
180
+ label?: string;
181
+ title?: string;
182
+ anchor?: string;
183
+ };
184
+ type FeedbackProps = {
185
+ /** The element whose text a reader may select. Pass a ref to it. */
186
+ container: RefObject<HTMLElement | null>;
187
+ /** Files the note. Resolve `{ ok: true }` when it is sent, or `{ ok: false, error }` to keep the form open with the error in place. */
188
+ onSend: (payload: FeedbackPayload) => Promise<FeedbackResult>;
189
+ /** Shortest selection that offers the pill. */
190
+ minChars?: number;
191
+ /** Shapes the chip and the payload from the heading above the selection. */
192
+ section?: (heading: Element | null) => FeedbackSection;
193
+ label?: string;
194
+ placeholder?: string;
195
+ /** The one line shown once the note is sent. */
196
+ sentMessage?: string;
197
+ };
198
+ declare function Feedback({ container, onSend, minChars, section, label, placeholder, sentMessage, }: FeedbackProps): react.ReactPortal;
199
+
159
200
  type ModalProps = {
160
201
  open: boolean;
161
202
  title: string;
@@ -759,6 +800,12 @@ type FileDropProps = {
759
800
  label?: string;
760
801
  /** The accepted types and the size limit, stated once beside the button. */
761
802
  note?: string;
803
+ /** Makes the drop an empty page's area: a dashed box around a first-run block with this title,
804
+ * the note and the button. The block stands in for the row and `children`, and the page
805
+ * leaves the area when the first file arrives, so it never shows a file in hand. */
806
+ title?: string;
807
+ /** Lets the picker take several files. */
808
+ multiple?: boolean;
762
809
  /** Filters the system picker only; the consumer still validates the file. */
763
810
  accept?: string;
764
811
  /** The words on the drop target. */
@@ -771,14 +818,17 @@ type FileDropProps = {
771
818
  /** Drives the target from a parent that owns the drag region. */
772
819
  dragging?: boolean;
773
820
  disabled?: boolean;
821
+ /** The first file chosen or dropped. */
774
822
  onFile?: (file: File) => void;
823
+ /** Every file chosen or dropped, together. A consumer may pass both props. */
824
+ onFiles?: (files: File[]) => void;
775
825
  onRemove?: () => void;
776
826
  onRetry?: () => void;
777
827
  /** What the region accepts the file for; the target covers it while dragging. */
778
828
  children?: ReactNode;
779
829
  className?: string;
780
830
  };
781
- declare function FileDrop({ label, note, accept, dropLabel, removeLabel, retryLabel, file, dragging, disabled, onFile, onRemove, onRetry, children, className, }: FileDropProps): react.JSX.Element;
831
+ declare function FileDrop({ label, note, title, multiple, accept, dropLabel, removeLabel, retryLabel, file, dragging, disabled, onFile, onFiles, onRemove, onRetry, children, className, }: FileDropProps): react.JSX.Element;
782
832
 
783
833
  type SearchFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'aria-label'> & {
784
834
  /** The control's name. A toolbar search box shows no label, so this is the
@@ -861,6 +911,42 @@ type AppShellProps = {
861
911
  };
862
912
  declare function AppShell({ sections, pathname, title, children, word, brand, brandHref, width, back, lede, actions, bandControl, account, onSignOut, searchLabel, searchShortLabel, defaultCollapsed, palette, renderLink }: AppShellProps): react.JSX.Element;
863
913
 
914
+ type FooterLink = {
915
+ label: string;
916
+ href?: string;
917
+ target?: string;
918
+ };
919
+ type FooterColumn = {
920
+ title?: string;
921
+ links: FooterLink[];
922
+ };
923
+ type FooterSocial = {
924
+ label: string;
925
+ href?: string;
926
+ icon?: 'github' | 'x' | 'linkedin' | 'mail';
927
+ };
928
+ type FooterProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
929
+ /** `full` is the marketing footer, `slim` a single legal row, `app` the in-product row. */
930
+ variant?: 'full' | 'slim' | 'app';
931
+ /** Product word beside the mark. Default `Strategy`. */
932
+ word?: string;
933
+ brandHref?: string;
934
+ /** Replaces the lockup. `false` hides the whole brand block: lockup, tagline and social links. Full variant only. */
935
+ brand?: ReactNode | false;
936
+ /** Short line under the brand. Full variant only. */
937
+ tagline?: string;
938
+ /** Link columns. Side by side above the phone step, stacked on a phone. Full variant only. */
939
+ columns?: FooterColumn[];
940
+ /** Contents of the link navigation. Takes the place of `columns`. Full variant only. */
941
+ links?: ReactNode;
942
+ social?: FooterSocial[];
943
+ legal?: ReactNode;
944
+ legalLinks?: FooterLink[];
945
+ /** Slot for `<AccentPicker>` and `<ThemeToggle>`. */
946
+ switcher?: ReactNode;
947
+ };
948
+ declare function Footer({ variant, word, brandHref, brand, tagline, columns, links, social, legal, legalLinks, switcher, className, ...rest }: FooterProps): react.JSX.Element;
949
+
864
950
  type EmptyStateVariant = 'first-run' | 'no-matches' | 'not-found' | 'not-yet-built';
865
951
  type EmptyStateProps = {
866
952
  variant?: EmptyStateVariant;
@@ -1148,4 +1234,4 @@ declare const Breadcrumbs: react.ForwardRefExoticComponent<Omit<Omit<react.Detai
1148
1234
  declare const PAGE_SIZES: readonly number[];
1149
1235
  declare const DEFAULT_PAGE_SIZE: number;
1150
1236
 
1151
- export { type Accent, AccentPicker, type AccentPickerProps, type AddFilter, AppShell, type AppShellProps, type AppShellSection, Avatar, type AvatarProps, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, BusyRegion, type BusyRegionProps, Button, type ButtonLinkProps, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, Chart, type ChartBridgeStep, type ChartBridgeTones, type ChartPeriod, type ChartProps, type ChartSeries, type ChartTone, CheckList, type CheckListProps, Checkbox, type CheckboxProps, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DatePicker, type DatePickerMode, type DatePickerPreset, type DatePickerProps, type DatePickerRange, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownAvatar, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, Field, type FieldControlProps, type FieldProps, FileDrop, type FileDropFile, type FileDropProps, type FileDropStatus, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, type NativeButtonProps, type NavTabBadge, type NavTabItem, NavTabs, type NavTabsProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, Pill, type PillProps, RowIdentity, type RowIdentityProps, SearchField, type SearchFieldProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, SidebarNav, type SidebarNavBadge, type SidebarNavItem, type SidebarNavLeaf, type SidebarNavProps, type SidebarNavSection, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, StatusDot, type StatusDotProps, Success, SuccessCheck, type SuccessCheckProps, type SuccessCountdown, SuccessPanel, type SuccessPanelProps, type SuccessProps, Switch, type SwitchProps, THEME_INIT_SCRIPT, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineEvent, type TimelineEventKind, type TimelineProps, Toast, type ToastNotice, type ToastProps, Tooltip, type TooltipProps, sortTableRows, useToast };
1237
+ export { type Accent, AccentPicker, type AccentPickerProps, type AddFilter, AppShell, type AppShellProps, type AppShellSection, Avatar, type AvatarProps, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, BusyRegion, type BusyRegionProps, Button, type ButtonLinkProps, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, Chart, type ChartBridgeStep, type ChartBridgeTones, type ChartPeriod, type ChartProps, type ChartSeries, type ChartTone, CheckList, type CheckListProps, Checkbox, type CheckboxProps, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DatePicker, type DatePickerMode, type DatePickerPreset, type DatePickerProps, type DatePickerRange, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownAvatar, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, Feedback, type FeedbackPayload, type FeedbackProps, type FeedbackResult, type FeedbackSection, Field, type FieldControlProps, type FieldProps, FileDrop, type FileDropFile, type FileDropProps, type FileDropStatus, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Footer, type FooterColumn, type FooterLink, type FooterProps, type FooterSocial, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, type NativeButtonProps, type NavTabBadge, type NavTabItem, NavTabs, type NavTabsProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, Pill, type PillProps, RowIdentity, type RowIdentityProps, SearchField, type SearchFieldProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, SidebarNav, type SidebarNavBadge, type SidebarNavItem, type SidebarNavLeaf, type SidebarNavProps, type SidebarNavSection, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, StatusDot, type StatusDotProps, Success, SuccessCheck, type SuccessCheckProps, type SuccessCountdown, SuccessPanel, type SuccessPanelProps, type SuccessProps, Switch, type SwitchProps, THEME_INIT_SCRIPT, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineEvent, type TimelineEventKind, type TimelineProps, Toast, type ToastNotice, type ToastProps, Tooltip, type TooltipProps, sortTableRows, useToast };