@nexdom/uimed-vue 2.0.0-beta.27 → 2.0.0-beta.29

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/AGENTS.md CHANGED
@@ -174,7 +174,14 @@ Use an existing composable (e.g. `use-toast`) as the reference, and deliver in t
174
174
  - Never write CSS or `<style>` blocks, and expose styling to consumers only through props.
175
175
  - Adjustments that Vuetify exposes as Sass variables (e.g. a font family or a line height) go in `src/styles/settings.scss`, which `vitePluginUimed()` compiles into Vuetify's stylesheets in the apps. That file only configures variables: still no CSS rules.
176
176
  - Don't add spacing to Vuetify components: no padding or margin utility classes (`pa-*`, `pt-6`, `px-4`, `ma-2`, ...) and no spacing props overriding the defaults. Vuetify already applies Material Design 3 spacing, and overriding it breaks what it handles on its own, such as button paddings and the scrollbar of scrollable content. If the default spacing looks wrong, stop and ask instead of adjusting it. The one accepted layout margin is `mt-auto` on `v-card-actions` (as in `USection`), which pushes the actions to the bottom of a full-height card without setting any spacing value.
177
- - Prefer a Vuetify component's own props to building its parts by hand (e.g. `title`/`text` on `v-card` instead of `v-card-item` > `v-card-title` > `v-card-text`). A non-spacing utility class is acceptable only when no prop covers the need (e.g. `text-wrap` on a card title), with a comment saying why.
177
+ - Prefer a Vuetify component's own props to building its parts by hand (e.g. `title`/`text` on `v-card` instead of `v-card-item` > `v-card-title` > `v-card-text`). A non-spacing utility class is acceptable only when no prop covers the need (e.g. `text-wrap` on a card title), with a comment saying why. Props covered by the shared composables below are the exception: they always go through them.
178
+ - Reuse the shared internal composables for props that recur across components, so every component maps them to Vuetify the same way, instead of mapping them again:
179
+ - `fullWidth`/`fullHeight`: `useFullWidth`/`useFullHeight` (`src/composables/dimensions/dimensions.ts`), applying Vuetify's `w-100`/`h-100` classes even where the component has `width`/`height` props.
180
+ - `alignX`/`alignY`: `useAlignX`/`useAlignY` (`src/composables/alignment/alignment.ts`), with the `AlignX`/`AlignY` types from the group's `types.ts`.
181
+ - `color`: `useVuetifyColor` (`src/composables/colors/use-vuetify-color.ts`), with the `ColorVariant` type from the group's `types.ts`.
182
+
183
+ A new prop that does the same as one of these takes its name and type. When a second component needs a mapping that only one component has, move it into a shared composable first.
184
+
178
185
  - Keep components thin: a component wires props, slots and events to Vuetify. Logic beyond that (focus management, queues, DOM lookups, comparisons) goes into an internal composable with its own unit tests.
179
186
  - Path aliases: `@/*` → `src/*`, `@e2e/*` → `e2e/*`.
180
187
  - Every public component follows this pattern to block access to internals and give it an editor-hover description:
@@ -1,4 +1,4 @@
1
- import { t as ButtonProps } from "./types-Zex9kf7C.js";
1
+ import { t as ButtonProps } from "./types-DNT_odv7.js";
2
2
  import { RouteLocationRaw } from "vue-router";
3
3
  //#region src/components/app-bar/types.d.ts
4
4
  /**
@@ -621,6 +621,12 @@ declare const __VLS_export$12: import("vue", { with: { "resolution-mode": "impor
621
621
  * Props exposed by the {@link Container} component.
622
622
  */
623
623
  type ContainerProps = {
624
+ /**
625
+ * Stretches the container to the whole height of its parent, which must have a height of its
626
+ * own, e.g. the content area of `UMain`.
627
+ * @default false
628
+ */
629
+ fullHeight?: boolean;
624
630
  /**
625
631
  * Component id to use on automated tests.
626
632
  */
@@ -652,6 +658,18 @@ type __VLS_WithSlots$8<T, S> = T & {
652
658
  };
653
659
  };
654
660
  //#endregion
661
+ //#region src/composables/alignment/types.d.ts
662
+ /**
663
+ * Horizontal alignment of a component's items: to the start, to the center or to the end,
664
+ * following the text direction.
665
+ */
666
+ type AlignX = "start" | "center" | "end";
667
+ /**
668
+ * Vertical alignment of a component's items: to the top, to the center, to the bottom, or
669
+ * stretched to the whole height available.
670
+ */
671
+ type AlignY = "start" | "center" | "end" | "stretch";
672
+ //#endregion
655
673
  //#region src/components/grid/row/types.d.ts
656
674
  /**
657
675
  * Props exposed by the {@link Row} component.
@@ -672,7 +690,7 @@ type RowProps = {
672
690
  * whole line, so the alignment has no visible effect.
673
691
  * @default "start"
674
692
  */
675
- alignX?: RowAlignX;
693
+ alignX?: AlignX;
676
694
  /**
677
695
  * Vertical alignment of the row's columns, relative to the tallest column on the same line.
678
696
  * Available options are:
@@ -685,10 +703,21 @@ type RowProps = {
685
703
  * `USection`s with `fullHeight`.
686
704
  *
687
705
  * Columns sit side by side only from the `sm` breakpoint up. Below it, each column takes a
688
- * whole line, so the alignment has no visible effect.
706
+ * whole line, so the alignment has no visible effect, unless the row has `fullHeight`: then
707
+ * the columns, as a group, are aligned within the row's height.
689
708
  * @default "start"
690
709
  */
691
- alignY?: RowAlignY;
710
+ alignY?: AlignY;
711
+ /**
712
+ * Stretches the row to the whole height of its parent: the visible content area of `UMain`
713
+ * (below its app bar) or a `UContainer` with `fullHeight`.
714
+ *
715
+ * Combine it with `alignY` to place the columns within that height, e.g. `alignY="center"`
716
+ * and `alignX="center"` to center a login form on the screen. A row with `fullHeight` takes
717
+ * the whole height by itself, so other rows next to it are pushed below the visible area.
718
+ * @default false
719
+ */
720
+ fullHeight?: boolean;
692
721
  /**
693
722
  * Renders the row as a list (`<ul>`), without the list's default indentation
694
723
  * and bullets, so assistive technologies announce its columns as the items
@@ -702,8 +731,6 @@ type RowProps = {
702
731
  */
703
732
  dataTestid?: string;
704
733
  };
705
- type RowAlignX = "start" | "center" | "end";
706
- type RowAlignY = "start" | "center" | "end" | "stretch";
707
734
  //#endregion
708
735
  //#region src/components/grid/row/row.vue.d.ts
709
736
  /**
@@ -723,10 +750,7 @@ type RowAlignY = "start" | "center" | "end" | "stretch";
723
750
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/layout | Row Guide}
724
751
  */
725
752
  declare const _default$13: typeof __VLS_export$10;
726
- declare const __VLS_export$10: __VLS_WithSlots$7<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RowProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<RowProps> & Readonly<{}>, {
727
- alignX: RowAlignX;
728
- alignY: RowAlignY;
729
- }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
753
+ declare const __VLS_export$10: __VLS_WithSlots$7<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RowProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<RowProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
730
754
  default?: (props: {}) => any;
731
755
  }>;
732
756
  type __VLS_WithSlots$7<T, S> = T & {
@@ -676,24 +676,48 @@ var navigation_menu_default = /* @__PURE__ */ defineComponent({
676
676
  }
677
677
  });
678
678
  //#endregion
679
+ //#region src/composables/dimensions/dimensions.ts
680
+ /**
681
+ * Vuetify's utility class that stretches a component to the whole width of its parent, for
682
+ * components with a `fullWidth` prop.
683
+ */
684
+ function useFullWidth(fullWidth) {
685
+ return computed(() => toValue(fullWidth) ? "w-100" : void 0);
686
+ }
687
+ /**
688
+ * Vuetify's utility class that stretches a component to the whole height of its parent, for
689
+ * components with a `fullHeight` prop. The parent must have a height of its own.
690
+ */
691
+ function useFullHeight(fullHeight) {
692
+ return computed(() => toValue(fullHeight) ? "h-100" : void 0);
693
+ }
694
+ //#endregion
679
695
  //#region src/components/grid/container/container.vue
680
696
  var container_default = /* @__PURE__ */ defineComponent({
681
697
  inheritAttrs: false,
682
698
  __name: "container",
683
- props: { dataTestid: {
684
- type: String,
685
- required: false
686
- } },
699
+ props: {
700
+ fullHeight: {
701
+ type: Boolean,
702
+ required: false
703
+ },
704
+ dataTestid: {
705
+ type: String,
706
+ required: false
707
+ }
708
+ },
687
709
  setup(__props) {
688
710
  const props = __props;
711
+ const heightClass = useFullHeight(() => props.fullHeight);
689
712
  return (_ctx, _cache) => {
690
713
  return openBlock(), createBlock(unref(VContainer), {
714
+ class: normalizeClass(unref(heightClass)),
691
715
  "data-testid": props.dataTestid,
692
716
  fluid: ""
693
717
  }, {
694
718
  default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
695
719
  _: 3
696
- }, 8, ["data-testid"]);
720
+ }, 8, ["class", "data-testid"]);
697
721
  };
698
722
  }
699
723
  });
@@ -772,6 +796,10 @@ var button_default = /* @__PURE__ */ defineComponent({
772
796
  type: Boolean,
773
797
  required: false
774
798
  },
799
+ fullWidth: {
800
+ type: Boolean,
801
+ required: false
802
+ },
775
803
  form: {
776
804
  type: String,
777
805
  required: false
@@ -789,6 +817,7 @@ var button_default = /* @__PURE__ */ defineComponent({
789
817
  const color = useVuetifyColor(() => props.color);
790
818
  const type = useButtonType(() => props.type);
791
819
  const form = useButtonForm(() => props.form);
820
+ const widthClass = useFullWidth(() => props.fullWidth);
792
821
  function onClick(event) {
793
822
  emit("click", event);
794
823
  }
@@ -801,6 +830,7 @@ var button_default = /* @__PURE__ */ defineComponent({
801
830
  color: unref(color),
802
831
  type: unref(type),
803
832
  form: unref(form),
833
+ class: normalizeClass(unref(widthClass)),
804
834
  onClick
805
835
  }, {
806
836
  loader: withCtx(() => [createVNode(unref(VProgressCircular), {
@@ -817,7 +847,8 @@ var button_default = /* @__PURE__ */ defineComponent({
817
847
  "variant",
818
848
  "color",
819
849
  "type",
820
- "form"
850
+ "form",
851
+ "class"
821
852
  ]);
822
853
  };
823
854
  }
@@ -1137,7 +1168,7 @@ var main_default = /* @__PURE__ */ defineComponent({
1137
1168
  loading: props.loading
1138
1169
  }), null, 16, ["modelValue", "loading"])) : createCommentVNode("v-if", true),
1139
1170
  createVNode(unref(VMain), null, {
1140
- default: withCtx(() => [createVNode(container_default, null, {
1171
+ default: withCtx(() => [createCommentVNode(" Full height, so the page's rows and containers with `fullHeight` have a height to fill "), createVNode(container_default, { "full-height": "" }, {
1141
1172
  default: withCtx(() => [
1142
1173
  renderSlot(_ctx.$slots, "default"),
1143
1174
  createVNode(toast_default),
@@ -1366,6 +1397,15 @@ var checkbox_default = /* @__PURE__ */ defineComponent({
1366
1397
  //#endregion
1367
1398
  //#region src/composables/inputs/date-time-field.ts
1368
1399
  /**
1400
+ * The menu's content is a dialog with the pickers. `aria-owns` is removed since the input can't
1401
+ * own the content, and the menu still adds `aria-expanded` and `aria-controls`.
1402
+ */
1403
+ const activatorProps = {
1404
+ role: "combobox",
1405
+ "aria-haspopup": "dialog",
1406
+ "aria-owns": void 0
1407
+ };
1408
+ /**
1369
1409
  * Extracts the date part (`YYYY-MM-DD`) of a value, or an empty string when
1370
1410
  * the type has no date.
1371
1411
  */
@@ -1423,6 +1463,31 @@ function useDateTimeFieldPickerBounds(props, selectedDate) {
1423
1463
  };
1424
1464
  });
1425
1465
  }
1466
+ /**
1467
+ * Makes the field's input the activator of the pickers' menu, so the menu's attributes are on an
1468
+ * element whose role accepts them.
1469
+ * @param isOpen - Whether the menu is open.
1470
+ * @param isDisabled - Whether the menu can't open, as when the field is disabled or readonly.
1471
+ * @param hasLabel - Whether the field has a label, which names the menu's dialog.
1472
+ */
1473
+ function useDateTimeFieldMenu(isOpen, isDisabled, hasLabel) {
1474
+ const inputId = useId();
1475
+ const activator = computed(() => toValue(isDisabled) ? void 0 : `#${inputId}`);
1476
+ const contentProps = computed(() => ({
1477
+ role: "dialog",
1478
+ "aria-labelledby": toValue(hasLabel) ? `${inputId}-label` : void 0
1479
+ }));
1480
+ function open() {
1481
+ if (!toValue(isDisabled)) isOpen.value = true;
1482
+ }
1483
+ return {
1484
+ inputId,
1485
+ activator,
1486
+ activatorProps,
1487
+ contentProps,
1488
+ open
1489
+ };
1490
+ }
1426
1491
  function getTimeBound(bound, type, selectedDate) {
1427
1492
  if (type === "datetime" && getDatePart(bound, type) !== selectedDate) return "";
1428
1493
  return getTimePart(bound, type);
@@ -1518,6 +1583,7 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1518
1583
  const draftTime = computed(() => draft.value.time ?? getTimePart(modelValue.value, props.type));
1519
1584
  const draftValue = computed(() => joinDateTime(props.type, draftDate.value, draftTime.value));
1520
1585
  const bounds = useDateTimeFieldPickerBounds(props, draftDate);
1586
+ const { inputId, activator, activatorProps, contentProps, open: openMenu } = useDateTimeFieldMenu(isMenuOpen, isMenuDisabled, () => !!props.label);
1521
1587
  watch(isMenuOpen, () => {
1522
1588
  draft.value = {};
1523
1589
  });
@@ -1541,6 +1607,7 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1541
1607
  }
1542
1608
  return (_ctx, _cache) => {
1543
1609
  return openBlock(), createBlock(unref(VTextField), {
1610
+ id: unref(inputId),
1544
1611
  "model-value": displayValue.value,
1545
1612
  "validation-value": modelValue.value,
1546
1613
  variant: unref(vuetifyVariant),
@@ -1554,13 +1621,17 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1554
1621
  hint: props.hint,
1555
1622
  clearable: isClearable.value,
1556
1623
  readonly: "",
1557
- "onClick:clear": clear
1624
+ "onClick:clear": clear,
1625
+ "onClick:control": unref(openMenu)
1558
1626
  }, {
1559
1627
  loader: withCtx((loader) => [createVNode(field_loader_default, normalizeProps(guardReactiveProps(loader)), null, 16)]),
1560
1628
  default: withCtx(() => [createVNode(unref(VMenu), {
1561
1629
  modelValue: isMenuOpen.value,
1562
1630
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isMenuOpen.value = $event),
1563
- activator: "parent",
1631
+ activator: unref(activator),
1632
+ target: "parent",
1633
+ "activator-props": unref(activatorProps),
1634
+ "content-props": unref(contentProps),
1564
1635
  location: "bottom start",
1565
1636
  "min-width": "0",
1566
1637
  disabled: isMenuDisabled.value,
@@ -1600,9 +1671,16 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1600
1671
  _: 1
1601
1672
  })]),
1602
1673
  _: 1
1603
- }, 8, ["modelValue", "disabled"])]),
1674
+ }, 8, [
1675
+ "modelValue",
1676
+ "activator",
1677
+ "activator-props",
1678
+ "content-props",
1679
+ "disabled"
1680
+ ])]),
1604
1681
  _: 1
1605
1682
  }, 8, [
1683
+ "id",
1606
1684
  "model-value",
1607
1685
  "validation-value",
1608
1686
  "variant",
@@ -1614,12 +1692,52 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1614
1692
  "label",
1615
1693
  "placeholder",
1616
1694
  "hint",
1617
- "clearable"
1695
+ "clearable",
1696
+ "onClick:control"
1618
1697
  ]);
1619
1698
  };
1620
1699
  }
1621
1700
  });
1622
1701
  //#endregion
1702
+ //#region src/composables/alignment/alignment.ts
1703
+ const alignXToClass = {
1704
+ start: "justify-start",
1705
+ center: "justify-center",
1706
+ end: "justify-end"
1707
+ };
1708
+ const alignYToClasses = {
1709
+ start: {
1710
+ items: "align-start",
1711
+ content: "align-content-start"
1712
+ },
1713
+ center: {
1714
+ items: "align-center",
1715
+ content: "align-content-center"
1716
+ },
1717
+ end: {
1718
+ items: "align-end",
1719
+ content: "align-content-end"
1720
+ },
1721
+ stretch: {
1722
+ items: "align-stretch",
1723
+ content: "align-content-stretch"
1724
+ }
1725
+ };
1726
+ /**
1727
+ * Vuetify's `justify-*` utility class for components with an `alignX` prop, laid out with flexbox.
1728
+ * Falls back to `"start"`.
1729
+ */
1730
+ function useAlignX(alignX) {
1731
+ return computed(() => alignXToClass[toValue(alignX) ?? "start"]);
1732
+ }
1733
+ /**
1734
+ * Vuetify's `align-*` and `align-content-*` utility classes for components with an `alignY` prop,
1735
+ * laid out with flexbox. Falls back to `"start"`.
1736
+ */
1737
+ function useAlignY(alignY) {
1738
+ return computed(() => alignYToClasses[toValue(alignY) ?? "start"]);
1739
+ }
1740
+ //#endregion
1623
1741
  //#region src/components/grid/row/row.vue
1624
1742
  var row_default = /* @__PURE__ */ defineComponent({
1625
1743
  inheritAttrs: false,
@@ -1627,13 +1745,15 @@ var row_default = /* @__PURE__ */ defineComponent({
1627
1745
  props: {
1628
1746
  alignX: {
1629
1747
  type: String,
1630
- required: false,
1631
- default: "start"
1748
+ required: false
1632
1749
  },
1633
1750
  alignY: {
1634
1751
  type: String,
1635
- required: false,
1636
- default: "start"
1752
+ required: false
1753
+ },
1754
+ fullHeight: {
1755
+ type: Boolean,
1756
+ required: false
1637
1757
  },
1638
1758
  list: {
1639
1759
  type: Boolean,
@@ -1646,27 +1766,20 @@ var row_default = /* @__PURE__ */ defineComponent({
1646
1766
  },
1647
1767
  setup(__props) {
1648
1768
  const props = __props;
1649
- const rowAlignXToClass = {
1650
- start: "justify-start",
1651
- center: "justify-center",
1652
- end: "justify-end"
1653
- };
1654
- const rowAlignYToClass = {
1655
- start: "align-start",
1656
- center: "align-center",
1657
- end: "align-end",
1658
- stretch: "align-stretch"
1659
- };
1660
- const alignXClass = computed(() => rowAlignXToClass[props.alignX]);
1661
- const alignYClass = computed(() => rowAlignYToClass[props.alignY]);
1769
+ const alignXClass = useAlignX(() => props.alignX);
1770
+ const alignYClasses = useAlignY(() => props.alignY);
1771
+ const heightClass = useFullHeight(() => props.fullHeight);
1772
+ const alignContentClass = computed(() => props.fullHeight ? alignYClasses.value.content : void 0);
1662
1773
  const tag = computed(() => props.list ? "ul" : void 0);
1663
1774
  const listClasses = computed(() => props.list ? "pa-0 ma-0" : void 0);
1664
1775
  return (_ctx, _cache) => {
1665
1776
  return openBlock(), createBlock(unref(VRow), {
1666
1777
  tag: tag.value,
1667
1778
  class: normalizeClass([
1668
- alignXClass.value,
1669
- alignYClass.value,
1779
+ unref(alignXClass),
1780
+ unref(alignYClasses).items,
1781
+ unref(heightClass),
1782
+ alignContentClass.value,
1670
1783
  listClasses.value
1671
1784
  ]),
1672
1785
  "data-testid": props.dataTestid
@@ -1854,25 +1967,27 @@ var section_default = /* @__PURE__ */ defineComponent({
1854
1967
  const textAlignClasses = useSectionTextAlign(() => props.textAlign);
1855
1968
  const title = computed(() => props.title || void 0);
1856
1969
  const subtitle = computed(() => props.subtitle || void 0);
1857
- const width = computed(() => props.fullWidth ? "100%" : void 0);
1858
- const height = computed(() => props.fullHeight ? "100%" : void 0);
1970
+ const widthClass = useFullWidth(() => props.fullWidth);
1971
+ const heightClass = useFullHeight(() => props.fullHeight);
1859
1972
  const showActions = computed(() => !!props.actions?.length);
1860
1973
  const skeletonType = computed(() => showActions.value ? "image, actions" : "image");
1861
1974
  return (_ctx, _cache) => {
1862
1975
  return openBlock(), createBlock(unref(VSkeletonLoader), {
1863
1976
  loading: props.loading,
1864
1977
  type: skeletonType.value,
1865
- width: width.value,
1866
- height: height.value
1978
+ class: normalizeClass([unref(widthClass), unref(heightClass)])
1867
1979
  }, {
1868
1980
  default: withCtx(() => [createCommentVNode(" The card and its actions have no alignment props, so `textAlign` uses utility classes "), createVNode(unref(VCard), {
1869
1981
  title: title.value,
1870
1982
  subtitle: subtitle.value,
1871
1983
  variant: unref(variant),
1872
- width: width.value,
1873
- height: height.value,
1874
1984
  "data-testid": props.dataTestid,
1875
- class: normalizeClass(["d-flex flex-column", unref(textAlignClasses).content])
1985
+ class: normalizeClass([
1986
+ "d-flex flex-column",
1987
+ unref(widthClass),
1988
+ unref(heightClass),
1989
+ unref(textAlignClasses).content
1990
+ ])
1876
1991
  }, {
1877
1992
  default: withCtx(() => [renderSlot(_ctx.$slots, "default"), showActions.value ? (openBlock(), createBlock(unref(VCardActions), {
1878
1993
  key: 0,
@@ -1891,8 +2006,6 @@ var section_default = /* @__PURE__ */ defineComponent({
1891
2006
  "title",
1892
2007
  "subtitle",
1893
2008
  "variant",
1894
- "width",
1895
- "height",
1896
2009
  "data-testid",
1897
2010
  "class"
1898
2011
  ])]),
@@ -1900,8 +2013,7 @@ var section_default = /* @__PURE__ */ defineComponent({
1900
2013
  }, 8, [
1901
2014
  "loading",
1902
2015
  "type",
1903
- "width",
1904
- "height"
2016
+ "class"
1905
2017
  ]);
1906
2018
  };
1907
2019
  }
@@ -1,4 +1,4 @@
1
- import { i as FeedbackColorVariant, n as ButtonVariant, r as ColorVariant } from "./types-Zex9kf7C.js";
1
+ import { i as FeedbackColorVariant, n as ButtonVariant, r as ColorVariant } from "./types-DNT_odv7.js";
2
2
  //#region src/composables/dialogs/types.d.ts
3
3
  interface ToastOptions {
4
4
  /**
@@ -38,6 +38,12 @@ type ButtonProps = {
38
38
  * @default false
39
39
  */
40
40
  loading?: boolean;
41
+ /**
42
+ * Stretches the button to the whole width of its parent, e.g. the only action of a form on a
43
+ * small screen.
44
+ * @default false
45
+ */
46
+ fullWidth?: boolean;
41
47
  /**
42
48
  * Associated [form](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/form) id.
43
49
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexdom/uimed-vue",
3
- "version": "2.0.0-beta.27",
3
+ "version": "2.0.0-beta.29",
4
4
  "description": "A ui framework for NEXDOM applications.",
5
5
  "keywords": [
6
6
  "lib",