@nxgt/material 3.86.2 → 3.88.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.
- package/CHANGELOG.md +22 -0
- package/README.md +2 -0
- package/dist/{alert-dialog-DZnt8PYE.js → alert-dialog-CEGs7LMN.js} +1 -1
- package/dist/{async-slice-D3OdV2BS.js → async-slice-CR0M95Jq.js} +1 -1
- package/dist/{button-MAL5an7L.js → button-h9hXBEQB.js} +1 -1
- package/dist/{calculator-C3a8YMwl.js → calculator-Dn_KL0b0.js} +10 -10
- package/dist/calculator-field.js +6 -6
- package/dist/{calculator-segment-BigMpjhn.js → calculator-segment-DMFptsDf.js} +1 -1
- package/dist/calculator.js +1 -1
- package/dist/charts.js +3 -3
- package/dist/{chip-DKAKoNxq.js → chip-C-RAjar5.js} +2 -2
- package/dist/{code-editor-B6dFQSUJ.js → code-editor-DApeIOZ3.js} +4 -4
- package/dist/code-editor.js +4 -4
- package/dist/{code-language-items-CXEMiWoF.js → code-language-items-CGtYfc1l.js} +2 -2
- package/dist/components/components.css +2 -0
- package/dist/components/ui/collections/marking-list/marking-list.css +16 -0
- package/dist/components/ui/primitives/toggle-group/toggle-group-connected.css +1 -1
- package/dist/components/ui/primitives/toggle-group/toggle-group-segmented.css +1 -1
- package/dist/components/ui/primitives/toggle-group/toggle-group-separate.css +1 -1
- package/dist/components/ui/primitives/toggle-group/toggle-group.css +12 -1
- package/dist/{components-BTukNsPn.js → components-BIATLurA.js} +16555 -15979
- package/dist/components.js +37 -37
- package/dist/{conversion-variant-BT5n4-jm.js → conversion-variant-Cf0sEmnS.js} +3 -3
- package/dist/{currency-field-t41sFYg_.js → currency-field-cwC7cqUE.js} +4 -4
- package/dist/{dialog-BjKiRXJg.js → dialog-Bul68q8u.js} +3 -3
- package/dist/dnd.js +1 -1
- package/dist/{dropdown-menu-IRFp4CH9.js → dropdown-menu-xUUE5X6T.js} +1 -1
- package/dist/editor.js +7 -7
- package/dist/{empty-state-C70prDDr.js → empty-state-CCRfjt0n.js} +1 -1
- package/dist/{financial-variant-BIpzs8IL.js → financial-variant-CYgRZzKT.js} +5 -5
- package/dist/{hooks-CjO11MS7.js → hooks-Dzc6xz5t.js} +2 -2
- package/dist/hooks.js +2 -2
- package/dist/{hover-card-cU_aJa18.js → hover-card-CZLFQwZv.js} +1 -1
- package/dist/i18n.js +3 -3
- package/dist/{icon-badge-D3KO6uEQ.js → icon-badge-0Xo9q7Ey.js} +1 -1
- package/dist/{icon-button-DrqNk1Ww.js → icon-button-DE1EcO2-.js} +1 -1
- package/dist/lib/components/ui/collections/filter/sections/filter-sections-classes.d.ts +4 -3
- package/dist/lib/components/ui/collections/index.d.ts +1 -0
- package/dist/lib/components/ui/collections/marking-list/index.d.ts +2 -0
- package/dist/lib/components/ui/collections/marking-list/marking-list.d.ts +11 -0
- package/dist/lib/components/ui/collections/marking-list/marking-list.utils.d.ts +18 -0
- package/dist/lib/components/ui/collections/marking-list/partials/marking-row-item.d.ts +16 -0
- package/dist/lib/components/ui/collections/marking-list/partials/marking-segments.d.ts +20 -0
- package/dist/lib/components/ui/collections/marking-list/partials/marking-set-remaining.d.ts +11 -0
- package/dist/lib/components/ui/collections/marking-list/partials/marking-tally.d.ts +14 -0
- package/dist/lib/components/ui/collections/marking-list/types.d.ts +74 -0
- package/dist/lib/components/ui/collections/marking-list/use-marking-expanded.d.ts +9 -0
- package/dist/lib/components/ui/collections/marking-list/use-marking-focus.d.ts +22 -0
- package/dist/lib/components/ui/collections/marking-list/use-marking-handlers.d.ts +11 -0
- package/dist/lib/components/ui/collections/marking-list/use-tally-speech.d.ts +16 -0
- package/dist/lib/components/ui/collections/page-footer/page-footer.d.ts +5 -1
- package/dist/lib/components/ui/collections/server-table/index.d.ts +1 -1
- package/dist/lib/components/ui/collections/server-table/server-table-paging.d.ts +8 -0
- package/dist/lib/components/ui/collections/server-table/types-paging.d.ts +6 -0
- package/dist/lib/components/ui/dates/half-day-range-field/half-day-end.d.ts +21 -0
- package/dist/lib/components/ui/dates/half-day-range-field/half-day-ends.d.ts +11 -0
- package/dist/lib/components/ui/dates/half-day-range-field/half-day-range-field.d.ts +39 -0
- package/dist/lib/components/ui/dates/half-day-range-field/half-day-range-form-field.d.ts +3 -0
- package/dist/lib/components/ui/dates/half-day-range-field/half-day-range.d.ts +25 -0
- package/dist/lib/components/ui/dates/half-day-range-field/index.d.ts +3 -0
- package/dist/lib/components/ui/dates/half-day-range-field/use-half-day-draft.d.ts +30 -0
- package/dist/lib/components/ui/dates/index.d.ts +1 -0
- package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
- package/dist/lib/i18n/resources/en/en.d.ts +17 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +17 -0
- package/dist/lib/i18n/resources/fr/fr.d.ts +17 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +17 -0
- package/dist/lib/i18n/resources/resources.d.ts +34 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/main.js +53 -53
- package/dist/map.js +7 -7
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/{percent-field-D47IlaPF.js → percent-field-BFwxazf1.js} +1 -1
- package/dist/{picker-surface-Cg4V4-E0.js → picker-surface-DkfTv_ft.js} +4 -4
- package/dist/{popover-Dzk4-l9U.js → popover-BM6xApJd.js} +1 -1
- package/dist/{pos-types-JOXMY4Y2.js → pos-types-CpTpT4vE.js} +1 -1
- package/dist/{pos-variant-B2mS8bMB.js → pos-variant-Bs5BUB1L.js} +4 -4
- package/dist/print.js +1 -1
- package/dist/{programmer-variant-C_Tl0P4_.js → programmer-variant-B1eI1fd0.js} +2 -2
- package/dist/{public-ByAsqBOf.js → public-CX7ik5Yg.js} +10 -10
- package/dist/{rich-code-block-CJAfqk6b.js → rich-code-block-CdVtxD75.js} +5 -5
- package/dist/{scientific-variant-CskM4MLV.js → scientific-variant-rfvJKxB4.js} +2 -2
- package/dist/{sortable-provider-ICS_vkLA.js → sortable-provider-BopzsciJ.js} +2 -2
- package/dist/{spinner-CweqX5A9.js → spinner-DcW21pN1.js} +1 -1
- package/dist/{tabs-95Y2LmnV.js → tabs-CdoBFtWx.js} +1 -1
- package/dist/theme-picker.js +2 -2
- package/dist/{theme-toggle-WAFkncYx.js → theme-toggle-Ch3GkDDU.js} +1 -1
- package/dist/{toolbar-items-BsgzHSNf.js → toolbar-items-CZ1lJXZZ.js} +4 -4
- package/dist/{translate-material-DTIAPmlU.js → translate-material-BrYBBZ66.js} +1 -1
- package/dist/{translator-BRZNhsy5.js → translator-DoVsjUff.js} +34 -0
- package/dist/{use-chat-composer-CleSUh_y.js → use-chat-composer-BjKhuLfT.js} +15 -15
- package/dist/{use-heading-spy-D8WbHJuK.js → use-heading-spy-CGTTRV2N.js} +4 -4
- package/dist/{use-material-translation-CCy1Me0h.js → use-material-translation-BdrItuwY.js} +1 -1
- package/dist/{use-return-focus-BA8G1qVU.js → use-return-focus-Cqzvj9R0.js} +1 -1
- package/docs/components/README.md +2 -1
- package/docs/components/data-table-filter-and-lists.md +103 -0
- package/docs/components/date-and-time.md +111 -0
- package/docs/components/primitives.md +4 -1
- package/docs/guides/forms.md +1 -0
- package/docs/guides/i18n.md +7 -0
- package/docs/guides/theming.md +1 -1
- package/docs/previews/data-table-filter-lists-markinglist.webp +0 -0
- package/docs/previews/date-time-halfdayrangefield.webp +0 -0
- package/docs/roadmap.md +7 -2
- package/lib/components/components.css +2 -0
- package/lib/components/ui/collections/marking-list/marking-list.css +16 -0
- package/lib/components/ui/primitives/toggle-group/toggle-group-connected.css +1 -1
- package/lib/components/ui/primitives/toggle-group/toggle-group-segmented.css +1 -1
- package/lib/components/ui/primitives/toggle-group/toggle-group-separate.css +1 -1
- package/lib/components/ui/primitives/toggle-group/toggle-group.css +12 -1
- package/package.json +2 -2
|
@@ -20,6 +20,7 @@ each change and, where one is left, the prop that keeps the old behaviour.
|
|
|
20
20
|
| <img src="../previews/date-time-timefield.webp" width="96" alt=""> | [TimeField](#timefield) | A time typed in segments or picked in a `TimePicker` (a bottom sheet on a phone) |
|
|
21
21
|
| <img src="../previews/date-time-timepicker.webp" width="96" alt=""> | [TimePicker](#timepicker) | Hour and minute tiles (or columns) with AM / PM |
|
|
22
22
|
| <img src="../previews/date-time-durationfield.webp" width="96" alt=""> | [DurationField](#durationfield) | Hours and minutes as a total in minutes, typed on one line: "1 h 29 min" |
|
|
23
|
+
| <img src="../previews/date-time-halfdayrangefield.webp" width="96" alt=""> | [HalfDayRangeField](#halfdayrangefield) | A range whose two ends are each a day plus morning or afternoon, ordered on the half |
|
|
23
24
|
| <img src="../previews/date-time-minimonth.webp" width="96" alt=""> | [MiniMonth](#minimonth) | Compact month navigator with event dots and a keyboard date grid |
|
|
24
25
|
| <img src="../previews/date-time-nowindicator.webp" width="96" alt=""> | [NowIndicator](#nowindicator) | The current-time line of a day schedule, moving each minute |
|
|
25
26
|
|
|
@@ -900,6 +901,116 @@ With `variant="fields"` the inputs are `textbox`es with the same names.
|
|
|
900
901
|
|
|
901
902
|
---
|
|
902
903
|
|
|
904
|
+
## HalfDayRangeField
|
|
905
|
+
|
|
906
|
+

|
|
907
|
+
|
|
908
|
+
A range counted to the half day (a long absence, a closure): each end is a day
|
|
909
|
+
(a `DateField`, typed or picked) plus a morning / afternoon toggle, and the end
|
|
910
|
+
is ordered on the half. The morning of day D is not after the afternoon of day
|
|
911
|
+
D; the afternoon of D to the morning of D is refused.
|
|
912
|
+
|
|
913
|
+
```tsx
|
|
914
|
+
import { useState } from 'react';
|
|
915
|
+
import { type HalfDayRange, HalfDayRangeField } from '@nxgt/material/components';
|
|
916
|
+
|
|
917
|
+
function Absence() {
|
|
918
|
+
const [value, setValue] = useState<HalfDayRange>();
|
|
919
|
+
return <HalfDayRangeField label="Absence" value={value} onValueChange={setValue} />;
|
|
920
|
+
}
|
|
921
|
+
// value: { start: { date: Date, half: 'morning' | 'afternoon' }, end: { … } }
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
With React Hook Form, `HalfDayRangeFormField` takes `control` and `name`, and its
|
|
925
|
+
rule refuses an unordered range in the form (the message is
|
|
926
|
+
`material.half-day-range.order`):
|
|
927
|
+
|
|
928
|
+
```tsx
|
|
929
|
+
import { useForm } from 'react-hook-form';
|
|
930
|
+
import { type HalfDayRange, HalfDayRangeFormField } from '@nxgt/material/components';
|
|
931
|
+
|
|
932
|
+
type Values = { absence?: HalfDayRange };
|
|
933
|
+
|
|
934
|
+
function AbsenceForm() {
|
|
935
|
+
const { control, handleSubmit } = useForm<Values>();
|
|
936
|
+
return (
|
|
937
|
+
<form onSubmit={handleSubmit((values) => save(values.absence))}>
|
|
938
|
+
<HalfDayRangeFormField control={control} name="absence" label="Absence" required />
|
|
939
|
+
</form>
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
Without a resolver the field checks the order itself (a `rules.validate` of your
|
|
945
|
+
own is kept beside it). React Hook Form ignores `rules` when a resolver is set,
|
|
946
|
+
so with zod state the order in the schema, or an end before the start is
|
|
947
|
+
submitted:
|
|
948
|
+
|
|
949
|
+
```tsx
|
|
950
|
+
import { z } from 'zod';
|
|
951
|
+
import { type HalfDayRange, isHalfDayRangeOrdered } from '@nxgt/material/components';
|
|
952
|
+
|
|
953
|
+
const schema = z.object({
|
|
954
|
+
absence: z
|
|
955
|
+
.custom<HalfDayRange>((v) => v != null, { message: 'Choose both days.' })
|
|
956
|
+
.refine(isHalfDayRangeOrdered, { message: 'The end cannot be before the start.' }),
|
|
957
|
+
});
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
| Prop | Type | Default | What it does |
|
|
961
|
+
| --- | --- | --- | --- |
|
|
962
|
+
| `value` | `HalfDayRange \| undefined` | | Controlled: `{ start: { date, half }, end: { date, half } }`; `date` is the local midnight of the day |
|
|
963
|
+
| `defaultValue` | `HalfDayRange` | | Uncontrolled: the range the field starts with and then keeps |
|
|
964
|
+
| `onValueChange` | `(value?: HalfDayRange) => void` | | The range as soon as both days are set, ordered or not; `undefined` while a day is missing |
|
|
965
|
+
| `label`, `helperText`, `error`, `required`, `disabled`, `className`, `id` | | | As on the other fields |
|
|
966
|
+
| `name` | `string` | | A test hook only (`data-pw` on the root, `.start` / `.end` on each end): the date inputs have no native `name`, so nothing is posted by a plain `<form>` |
|
|
967
|
+
| `minDate`, `maxDate` | `Date` | | Bound both ends; the end's calendar also starts at the start's day |
|
|
968
|
+
| `disabledDays`, `locale` | | | As on `DateField` (`timeZone` is not forwarded: days are the local ones) |
|
|
969
|
+
|
|
970
|
+
**What the field says in each state:**
|
|
971
|
+
|
|
972
|
+
| State | `onValueChange` | On screen |
|
|
973
|
+
| --- | --- | --- |
|
|
974
|
+
| A day is missing (start or end empty, or half typed) | `undefined` | The other end is kept; no message |
|
|
975
|
+
| Both days set, end on or after the start on the half | the range | |
|
|
976
|
+
| Both days set, end before the start on the half | the range, as entered | "The end cannot be before the start." under the field, `aria-invalid` on the halves, announced politely; in a form without a resolver, `HalfDayRangeFormField` makes it a field error (with zod, use the `refine` above) |
|
|
977
|
+
| `value` reset to `undefined` from outside (a form `reset`) | | Both days are emptied, the halves go back to morning and afternoon, unless the emitted value was already `undefined` (a half-typed start or a cleared end stays: give the field a `key` that changes on reset) |
|
|
978
|
+
|
|
979
|
+
A new range starts on the morning (start) and the afternoon (end), so one picked
|
|
980
|
+
day is a full day. Each end has its own accessible names ("Start date", "Start
|
|
981
|
+
half-day", "End date", "End half-day": `material.dates.start` / `end` and
|
|
982
|
+
`material.half-day-range.*`, see the [i18n guide](../guides/i18n.md)).
|
|
983
|
+
|
|
984
|
+
The value holds `Date`s: store a day with `format(date, 'yyyy-MM-dd')` (date-fns),
|
|
985
|
+
not `toISOString()`, which moves it to UTC and can shift the day.
|
|
986
|
+
|
|
987
|
+
```tsx
|
|
988
|
+
import {
|
|
989
|
+
compareHalfDays,
|
|
990
|
+
halfDaysIn,
|
|
991
|
+
type HalfDayRange,
|
|
992
|
+
isHalfDayRangeOrdered,
|
|
993
|
+
} from '@nxgt/material/components';
|
|
994
|
+
|
|
995
|
+
const range: HalfDayRange = {
|
|
996
|
+
start: { date: new Date(2030, 5, 3), half: 'morning' },
|
|
997
|
+
end: { date: new Date(2030, 5, 4), half: 'afternoon' },
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
isHalfDayRangeOrdered(range); // true: the end is not before the start on the half
|
|
1001
|
+
halfDaysIn(range); // 4: Monday morning and afternoon, Tuesday morning and afternoon
|
|
1002
|
+
compareHalfDays(range.start, range.end); // -3: negative when the first comes first
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
`HALF_DAYS` (`['morning', 'afternoon']`, in the order of the day) is exported too.
|
|
1006
|
+
|
|
1007
|
+
**Emits:** `HalfDayRange | undefined`.
|
|
1008
|
+
**Form wrapper:** `HalfDayRangeFormField` — `control` and `name`, see
|
|
1009
|
+
[forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
|
|
1010
|
+
**Storybook:** `Date & time/HalfDayRangeField` and `Date & time/HalfDayRangeField/Form field` · **Vue:** not yet (#2555 tracks the twin)
|
|
1011
|
+
|
|
1012
|
+
---
|
|
1013
|
+
|
|
903
1014
|
## MiniMonth
|
|
904
1015
|
|
|
905
1016
|

|
|
@@ -1142,7 +1142,10 @@ page's: Radix writes `dir="ltr"` on the group unless told. A `segmented`
|
|
|
1142
1142
|
group of 9 items or more has no sliding pill: the checked item paints its
|
|
1143
1143
|
own.
|
|
1144
1144
|
|
|
1145
|
-
|
|
1145
|
+
Under a coarse pointer (a touch screen) every item is at least 44×44 px, in
|
|
1146
|
+
every variant, size and orientation, icon-only included.
|
|
1147
|
+
|
|
1148
|
+
**Storybook:** `Primitives/ToggleGroup`, `Guides/Accessibility/Touch targets/Toggle group` · **Vue:** `ToggleGroup`, `ToggleGroupItem`
|
|
1146
1149
|
|
|
1147
1150
|
---
|
|
1148
1151
|
|
package/docs/guides/forms.md
CHANGED
|
@@ -523,6 +523,7 @@ or fails validation.
|
|
|
523
523
|
| `DateRangeField` · `DateRangeFormField` | `DateRange \| undefined`: `{ from: Date \| undefined; to?: Date }` | `undefined` |
|
|
524
524
|
| `TimeField` · `TimeFormField` | `Date \| undefined` (with `timeZone`, the true instant). With `asString`: `'HH:mm'`. While empty it shows its `placeholder` | `undefined` / `''` |
|
|
525
525
|
| `DurationField` · `DurationFormField` | `number \| null`: total minutes (hours × 60 + minutes) | `null` |
|
|
526
|
+
| `HalfDayRangeField` · `HalfDayRangeFormField` | `HalfDayRange \| undefined`: `{ start: { date, half }, end: { date, half } }`, `half` `'morning' \| 'afternoon'`; `undefined` while a day is missing; an end before the start is the value, refused by the wrapper's rule (`material.half-day-range.order`) | `undefined` |
|
|
526
527
|
|
|
527
528
|
### Selection & choice
|
|
528
529
|
|
package/docs/guides/i18n.md
CHANGED
|
@@ -397,6 +397,13 @@ dates", "Saisir les dates") on `DateRangeField`. Its hero says
|
|
|
397
397
|
`material.dates.select-date` ("Select date", "Choisir la date") while the date
|
|
398
398
|
is empty, `material.dates.select-dates` on `DateRangeField`, and the Cancel of
|
|
399
399
|
a date-time picker reads `material.buttons.cancel` ("Cancel", "Annuler").
|
|
400
|
+
`HalfDayRangeField` names its ends `material.dates.start` / `end` and its two
|
|
401
|
+
halves `material.half-day-range.start-half` ("Start half-day", "Demi-journée de
|
|
402
|
+
début") and `end-half` ("End half-day", "Demi-journée de fin"); the toggles read
|
|
403
|
+
`material.half-day-range.morning` ("Morning", "Matin") and `afternoon`
|
|
404
|
+
("Afternoon", "Après-midi"), and an end before the start says
|
|
405
|
+
`material.half-day-range.order` ("The end cannot be before the start.", "La fin
|
|
406
|
+
ne peut pas précéder le début.").
|
|
400
407
|
`DateRangeField`'s preset list is a group named by
|
|
401
408
|
`material.date-range-field.presets` ("Presets", "Plages prédéfinies"); its
|
|
402
409
|
built-in presets read `material.date-range-field.preset.today`,
|
package/docs/guides/theming.md
CHANGED
|
@@ -1167,7 +1167,7 @@ are, without growing what is painted (nothing changes for a mouse):
|
|
|
1167
1167
|
`trailing` button of a `TextField`), an autocomplete chip's remove button
|
|
1168
1168
|
(padding the background is clipped out of, with a negative margin, so the
|
|
1169
1169
|
chip and the drawn disc keep their size), and a table's select-all and
|
|
1170
|
-
row-select checkboxes, which sit in a 44x44 `<label>` that toggles them.
|
|
1170
|
+
row-select checkboxes, which sit in a 44x44 `<label>` that toggles them, `AppBreadcrumb` and `BreadcrumbLink` crumbs (at every width), the `FilterBar` / `ServerTable` search input (at both densities), and the move up / move down buttons of `RepeatableGroup` and `ChoiceListFormField` (`reorderable`).
|
|
1171
1171
|
- **The label or row that toggles it is 44px tall** (and at least 44px wide):
|
|
1172
1172
|
a `Checkbox` with a `label`, a `Switch` with a `placeholder` (its row), and
|
|
1173
1173
|
a `RadioGroup` option. The box itself stays 20px or 32px: a finger anywhere
|
|
Binary file
|
|
Binary file
|
package/docs/roadmap.md
CHANGED
|
@@ -167,6 +167,7 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
167
167
|
pill. What changes on upgrade:
|
|
168
168
|
[The field look (2.x)](guides/field-look-2-x.md)
|
|
169
169
|
- **`TotalsList`** — the on-screen `PrintTotals` (#2490): React only for now; Vue twin is #2492.
|
|
170
|
+
- **`MarkingList`** — people in rows with a shared segmented choice, a detail slot, locked rows, "set remaining to" and a live tally (#2547): React only for now; Vue twin is #2549.
|
|
170
171
|
|
|
171
172
|
## Next
|
|
172
173
|
|
|
@@ -254,8 +255,6 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
254
255
|
slot; the bar's `views` slot is planned with it. They are meant to replace
|
|
255
256
|
the legacy `FilterPresets`. Tracked in [#1876](https://github.com/softistx/nxgt-material/issues/1876).
|
|
256
257
|
|
|
257
|
-
- **Cursor trail cap** — `ServerTable` and `PageFooter` keep cursor URLs short: the trail is encoded once and capped by `maxTrail` (20 by default) with an exact page count, and `totalCount` becomes optional for APIs that do not count.
|
|
258
|
-
|
|
259
258
|
## Later
|
|
260
259
|
|
|
261
260
|
- **A lighter first load for the app shell** — `ActivityLayout` pulls about
|
|
@@ -380,6 +379,12 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
380
379
|
|
|
381
380
|
## Shipped
|
|
382
381
|
|
|
382
|
+
- **Cursor trail cap** — `ServerTable` and `PageFooter` keep cursor URLs short:
|
|
383
|
+
each trail entry is encoded once and the trail is capped by `maxTrail` (20 by
|
|
384
|
+
default, a prop on each) behind a counted cut mark, so the "21–40 of N" range
|
|
385
|
+
stays exact; Previous from the cut goes back to the first page. (`ServerTable`'s
|
|
386
|
+
`totalCount` was already optional, with no range then; shipped earlier.)
|
|
387
|
+
|
|
383
388
|
- **App shell header refresh: the TopAppBar family (next minor)** — `TopAppBar`
|
|
384
389
|
takes four sizes (`small`, `medium-flexible`, `large-flexible`, `search`), an
|
|
385
390
|
`align`, a `title` that is the page's `h1` with a `subtitle`, and a collapse
|
|
@@ -148,6 +148,8 @@
|
|
|
148
148
|
@import "./ui/display/vote-tally/vote-tally.css";
|
|
149
149
|
/* TubeCap: a specimen tube chip, cap colours fixed by the tube convention. */
|
|
150
150
|
@import "./ui/display/tube-cap/tube-cap.css";
|
|
151
|
+
/* MarkingList: forced-colours rules for the chosen segment. */
|
|
152
|
+
@import "./ui/collections/marking-list/marking-list.css";
|
|
151
153
|
/* SecretCard: a face that is not rendered until it is revealed. */
|
|
152
154
|
@import "./ui/display/secret-card/secret-card.css";
|
|
153
155
|
/* Alert and Banner span the row in the form grids (#1497). */
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* MarkingList: the chosen segment is also a check and a border; in forced
|
|
2
|
+
* colours it takes the system's selected colours, as the toggle group does. */
|
|
3
|
+
@media (forced-colors: active) {
|
|
4
|
+
.nxgt-marking-segment {
|
|
5
|
+
border: 1px solid ButtonText;
|
|
6
|
+
}
|
|
7
|
+
.nxgt-marking-segment[aria-pressed="true"] {
|
|
8
|
+
forced-color-adjust: none;
|
|
9
|
+
background: SelectedItem;
|
|
10
|
+
color: SelectedItemText;
|
|
11
|
+
}
|
|
12
|
+
.nxgt-marking-segment:focus-visible {
|
|
13
|
+
outline: 2px solid Highlight;
|
|
14
|
+
outline-offset: 2px;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
box-shadow 160ms ease-out;
|
|
44
44
|
}
|
|
45
45
|
[data-variant="connected"] > .nxgt-toggle-group-item[data-icon-only] {
|
|
46
|
-
width: calc(var(--tg-iw) + 2 * var(--sq));
|
|
46
|
+
width: max(var(--tg-touch), calc(var(--tg-iw) + 2 * var(--sq)));
|
|
47
47
|
padding-inline: 0;
|
|
48
48
|
}
|
|
49
49
|
/* Outer corners: the row's start and end, a column's top and bottom; a
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
border-radius: var(--tg-inner);
|
|
56
56
|
}
|
|
57
57
|
[data-variant="segmented"] > .nxgt-toggle-group-item[data-icon-only] {
|
|
58
|
-
min-width: calc(var(--tg-h) + 0.25rem);
|
|
58
|
+
min-width: max(var(--tg-touch), calc(var(--tg-h) + 0.25rem));
|
|
59
59
|
}
|
|
60
60
|
[data-variant="segmented"]
|
|
61
61
|
> .nxgt-toggle-group-item:hover:not(
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
scale var(--tg-fast) var(--tg-spring-fast);
|
|
66
66
|
}
|
|
67
67
|
[data-variant="separate"] > .nxgt-toggle-group-item[data-icon-only] {
|
|
68
|
-
width: calc(var(--tg-h) + 0.25rem);
|
|
68
|
+
width: max(var(--tg-touch), calc(var(--tg-h) + 0.25rem));
|
|
69
69
|
padding-inline-start: 0.25rem;
|
|
70
70
|
}
|
|
71
71
|
[data-variant="separate"] > .nxgt-toggle-group-item:hover:not(:disabled) {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
--tg-spring: var(--nxgt-spring);
|
|
14
14
|
--tg-fast: var(--nxgt-spring-fast-duration);
|
|
15
15
|
--tg-slow: var(--nxgt-spring-duration);
|
|
16
|
+
--tg-touch: 0px;
|
|
16
17
|
--tg-h: 2.25rem;
|
|
17
18
|
--tg-pad: 1rem;
|
|
18
19
|
--tg-font: 0.875rem;
|
|
@@ -63,7 +64,8 @@
|
|
|
63
64
|
justify-content: center;
|
|
64
65
|
gap: var(--tg-lead-gap);
|
|
65
66
|
box-sizing: border-box;
|
|
66
|
-
min-width: var(--tg-h);
|
|
67
|
+
min-width: max(var(--tg-touch), var(--tg-h));
|
|
68
|
+
min-height: var(--tg-touch);
|
|
67
69
|
height: var(--tg-h);
|
|
68
70
|
padding-inline: var(--tg-pad);
|
|
69
71
|
border: 0;
|
|
@@ -104,6 +106,15 @@
|
|
|
104
106
|
cursor: not-allowed;
|
|
105
107
|
opacity: 0.45;
|
|
106
108
|
}
|
|
109
|
+
/* Touch: every item is a 44x44 box on a coarse pointer (a size sm item is
|
|
110
|
+
* 32px, an icon-only one about 36 to 42px wide). --tg-touch is the floor
|
|
111
|
+
* the item's min-width and min-height, and the variants' icon-only widths,
|
|
112
|
+
* take through max(); a fine pointer keeps the sizes above. */
|
|
113
|
+
@media (pointer: coarse) {
|
|
114
|
+
.nxgt-toggle-group {
|
|
115
|
+
--tg-touch: 2.75rem;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
107
118
|
|
|
108
119
|
/* The check a selected label-only item draws in (connected only). At rest
|
|
109
120
|
* it takes no room: no width, and a margin that cancels the gap. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/material",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.88.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"email": "stevegires@gmail.com"
|
|
@@ -390,7 +390,7 @@
|
|
|
390
390
|
"docs:previews": "rm -rf node_modules/.cache/nxgt-preview-free/missing && NXGT_PREVIEW_FREE=1 vitest run --project previews && bun .storybook/preview-free-report.ts"
|
|
391
391
|
},
|
|
392
392
|
"dependencies": {
|
|
393
|
-
"@nxgt/material-core": "^0.
|
|
393
|
+
"@nxgt/material-core": "^0.52.0",
|
|
394
394
|
"@base-ui/react": "^1.6.0",
|
|
395
395
|
"@dnd-kit/core": "^6.3.1",
|
|
396
396
|
"@dnd-kit/sortable": "^10.0.0",
|