mithril-materialized 3.7.0 → 3.8.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/dist/index.umd.js CHANGED
@@ -10715,6 +10715,126 @@
10715
10715
  };
10716
10716
  };
10717
10717
 
10718
+ /**
10719
+ * ToggleButton component.
10720
+ *
10721
+ * A button that can be toggled on/off. Typically used within a ToggleGroup
10722
+ * to create grouped button controls where one or more buttons can be selected.
10723
+ *
10724
+ * @example
10725
+ * ```typescript
10726
+ * m(ToggleButton, {
10727
+ * value: 'bold',
10728
+ * iconName: 'format_bold',
10729
+ * checked: true,
10730
+ * tooltip: 'Bold',
10731
+ * onchange: () => console.log('Toggled')
10732
+ * })
10733
+ * ```
10734
+ */
10735
+ const ToggleButton = () => {
10736
+ return {
10737
+ view: ({ attrs }) => {
10738
+ const { checked, iconName, icon, label, onchange, className, tooltip } = attrs, rest = __rest(attrs, ["checked", "iconName", "icon", "label", "onchange", "className", "tooltip"]);
10739
+ const classes = [className, checked ? 'checked' : ''].filter(Boolean).join(' ');
10740
+ return m('button.btn-flat.waves-effect.toggle-button', Object.assign(Object.assign({}, rest), { className: classes, title: tooltip, onclick: () => {
10741
+ if (onchange) {
10742
+ onchange();
10743
+ }
10744
+ }, onmousedown: WavesEffect.onMouseDown, onmouseup: WavesEffect.onMouseUp, onmouseleave: WavesEffect.onMouseLeave, ontouchstart: WavesEffect.onTouchStart, ontouchend: WavesEffect.onTouchEnd }), [icon, iconName && m(Icon, { iconName, className: attrs.iconClass }), label]);
10745
+ },
10746
+ };
10747
+ };
10748
+
10749
+ /**
10750
+ * ToggleGroup component.
10751
+ *
10752
+ * A group of toggle buttons that can operate in single-select or multi-select mode.
10753
+ * The component supports both controlled and uncontrolled modes.
10754
+ *
10755
+ * **Controlled mode**: Manage the state externally using the `value` prop.
10756
+ * **Uncontrolled mode**: Let the component manage its own state using `defaultValue`.
10757
+ *
10758
+ * @example
10759
+ * ```typescript
10760
+ * // Single-select, controlled mode
10761
+ * let selected = 'left';
10762
+ * m(ToggleGroup, {
10763
+ * value: selected,
10764
+ * onchange: (v) => selected = v,
10765
+ * items: [
10766
+ * { value: 'left', iconName: 'format_align_left', tooltip: 'Align Left' },
10767
+ * { value: 'center', iconName: 'format_align_center', tooltip: 'Align Center' },
10768
+ * { value: 'right', iconName: 'format_align_right', tooltip: 'Align Right' }
10769
+ * ]
10770
+ * });
10771
+ *
10772
+ * // Multi-select, controlled mode
10773
+ * let selected = ['bold', 'italic'];
10774
+ * m(ToggleGroup, {
10775
+ * multiple: true,
10776
+ * value: selected,
10777
+ * onchange: (v) => selected = v,
10778
+ * items: [
10779
+ * { value: 'bold', iconName: 'format_bold', tooltip: 'Bold' },
10780
+ * { value: 'italic', iconName: 'format_italic', tooltip: 'Italic' },
10781
+ * { value: 'underline', iconName: 'format_underlined', tooltip: 'Underline' }
10782
+ * ]
10783
+ * });
10784
+ *
10785
+ * // Uncontrolled mode
10786
+ * m(ToggleGroup, {
10787
+ * defaultValue: 'left',
10788
+ * onchange: (v) => console.log('Changed to:', v),
10789
+ * items: [...]
10790
+ * });
10791
+ * ```
10792
+ */
10793
+ const ToggleGroup = () => {
10794
+ let internalValue;
10795
+ const handleSelect = (attrs, item, currentValue) => {
10796
+ if (attrs.disabled || item.disabled) {
10797
+ return;
10798
+ }
10799
+ const { value, multiple, onchange } = attrs;
10800
+ const isControlled = value !== undefined;
10801
+ if (multiple) {
10802
+ const currentValues = (Array.isArray(currentValue) ? currentValue : currentValue !== undefined ? [currentValue] : []);
10803
+ const newValues = currentValues.includes(item.value)
10804
+ ? currentValues.filter((v) => v !== item.value)
10805
+ : [...currentValues, item.value];
10806
+ if (!isControlled) {
10807
+ internalValue = newValues;
10808
+ }
10809
+ if (onchange) {
10810
+ onchange(newValues);
10811
+ }
10812
+ }
10813
+ else {
10814
+ const newValue = item.value;
10815
+ if (!isControlled) {
10816
+ internalValue = newValue;
10817
+ }
10818
+ if (onchange) {
10819
+ onchange(newValue);
10820
+ }
10821
+ }
10822
+ };
10823
+ return {
10824
+ oninit: ({ attrs }) => {
10825
+ internalValue = attrs.defaultValue;
10826
+ },
10827
+ view: ({ attrs }) => {
10828
+ const { value, items, multiple } = attrs;
10829
+ const isControlled = value !== undefined;
10830
+ const currentValue = isControlled ? value : internalValue;
10831
+ return m('.toggle-group', items.map((item) => m(ToggleButton, Object.assign(Object.assign({}, item), { checked: multiple && Array.isArray(currentValue)
10832
+ ? currentValue.includes(item.value)
10833
+ : currentValue === item.value, onchange: () => handleSelect(attrs, item, currentValue) }))));
10834
+ },
10835
+ };
10836
+ };
10837
+
10718
10838
  /**
10719
10839
  * @fileoverview Core TypeScript utility types for mithril-materialized library
10720
10840
  * These types improve type safety and developer experience across all components
@@ -10810,6 +10930,7 @@
10810
10930
  exports.Timeline = Timeline;
10811
10931
  exports.Toast = Toast;
10812
10932
  exports.ToastComponent = ToastComponent;
10933
+ exports.ToggleGroup = ToggleGroup;
10813
10934
  exports.Tooltip = Tooltip;
10814
10935
  exports.TooltipComponent = TooltipComponent;
10815
10936
  exports.TreeView = TreeView;
@@ -0,0 +1,46 @@
1
+ import { FactoryComponent, Attributes, Vnode } from 'mithril';
2
+ /**
3
+ * Attributes for the ToggleButton component.
4
+ *
5
+ * A toggle button is a button that can be in a checked or unchecked state.
6
+ * It is typically used within a ToggleGroup to create button groups where
7
+ * one or more buttons can be selected.
8
+ */
9
+ export interface ToggleButtonAttrs extends Attributes {
10
+ /** The value of the button. This is returned when the button is selected. */
11
+ value: string | number;
12
+ /** The label text to display next to the icon. */
13
+ label?: string;
14
+ /** The name of the Material Design icon to display. */
15
+ iconName?: string;
16
+ /** A custom SVG icon vnode to display instead of a Material icon. */
17
+ icon?: Vnode<any, any>;
18
+ /** Additional CSS class for the icon element. */
19
+ iconClass?: string;
20
+ /** Whether the button is in a checked/selected state. */
21
+ checked?: boolean;
22
+ /** Whether the button is disabled and cannot be interacted with. */
23
+ disabled?: boolean;
24
+ /** Optional tooltip text to display on hover. */
25
+ tooltip?: string;
26
+ /** Callback function invoked when the button is clicked. */
27
+ onchange?: () => void;
28
+ }
29
+ /**
30
+ * ToggleButton component.
31
+ *
32
+ * A button that can be toggled on/off. Typically used within a ToggleGroup
33
+ * to create grouped button controls where one or more buttons can be selected.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * m(ToggleButton, {
38
+ * value: 'bold',
39
+ * iconName: 'format_bold',
40
+ * checked: true,
41
+ * tooltip: 'Bold',
42
+ * onchange: () => console.log('Toggled')
43
+ * })
44
+ * ```
45
+ */
46
+ export declare const ToggleButton: FactoryComponent<ToggleButtonAttrs>;
@@ -0,0 +1,84 @@
1
+ import { FactoryComponent, Attributes } from 'mithril';
2
+ import { ToggleButtonAttrs } from './toggle-button';
3
+ /**
4
+ * Attributes for the ToggleGroup component.
5
+ *
6
+ * A toggle group is a container for multiple toggle buttons that manages their
7
+ * selection state. It can operate in single-select or multi-select mode.
8
+ */
9
+ export interface ToggleGroupAttrs extends Attributes {
10
+ /**
11
+ * The current value(s) of the toggle group (controlled mode).
12
+ * - Single-select: a single value
13
+ * - Multi-select: an array of values
14
+ */
15
+ value?: string | number | Array<string | number>;
16
+ /**
17
+ * The default value(s) for uncontrolled mode.
18
+ * Use this when you want the component to manage its own state.
19
+ */
20
+ defaultValue?: string | number | Array<string | number>;
21
+ /** Whether all buttons in the group are disabled. */
22
+ disabled?: boolean;
23
+ /**
24
+ * Callback invoked when the selection changes.
25
+ * @param value - The new value (single value or array depending on `multiple`)
26
+ */
27
+ onchange?: (value: string | number | Array<string | number>) => void;
28
+ /**
29
+ * Array of button configurations to display in the group.
30
+ * Each item can have its own icon, label, tooltip, and disabled state.
31
+ */
32
+ items: Array<ToggleButtonAttrs>;
33
+ /**
34
+ * Whether to allow multiple buttons to be selected simultaneously.
35
+ * - false (default): only one button can be selected at a time
36
+ * - true: multiple buttons can be selected
37
+ */
38
+ multiple?: boolean;
39
+ }
40
+ /**
41
+ * ToggleGroup component.
42
+ *
43
+ * A group of toggle buttons that can operate in single-select or multi-select mode.
44
+ * The component supports both controlled and uncontrolled modes.
45
+ *
46
+ * **Controlled mode**: Manage the state externally using the `value` prop.
47
+ * **Uncontrolled mode**: Let the component manage its own state using `defaultValue`.
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // Single-select, controlled mode
52
+ * let selected = 'left';
53
+ * m(ToggleGroup, {
54
+ * value: selected,
55
+ * onchange: (v) => selected = v,
56
+ * items: [
57
+ * { value: 'left', iconName: 'format_align_left', tooltip: 'Align Left' },
58
+ * { value: 'center', iconName: 'format_align_center', tooltip: 'Align Center' },
59
+ * { value: 'right', iconName: 'format_align_right', tooltip: 'Align Right' }
60
+ * ]
61
+ * });
62
+ *
63
+ * // Multi-select, controlled mode
64
+ * let selected = ['bold', 'italic'];
65
+ * m(ToggleGroup, {
66
+ * multiple: true,
67
+ * value: selected,
68
+ * onchange: (v) => selected = v,
69
+ * items: [
70
+ * { value: 'bold', iconName: 'format_bold', tooltip: 'Bold' },
71
+ * { value: 'italic', iconName: 'format_italic', tooltip: 'Italic' },
72
+ * { value: 'underline', iconName: 'format_underlined', tooltip: 'Underline' }
73
+ * ]
74
+ * });
75
+ *
76
+ * // Uncontrolled mode
77
+ * m(ToggleGroup, {
78
+ * defaultValue: 'left',
79
+ * onchange: (v) => console.log('Changed to:', v),
80
+ * items: [...]
81
+ * });
82
+ * ```
83
+ */
84
+ export declare const ToggleGroup: FactoryComponent<ToggleGroupAttrs>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mithril-materialized",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "A materialize library for mithril.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -0,0 +1,36 @@
1
+ .toggle-group {
2
+ display: inline-flex;
3
+ border-radius: 4px;
4
+ overflow: hidden;
5
+ border: 1px solid var(--mm-border-color, #e0e0e0);
6
+
7
+ .toggle-button {
8
+ margin: 0;
9
+ border-radius: 0;
10
+ border-right: 1px solid var(--mm-border-color, #e0e0e0);
11
+
12
+ &:last-child {
13
+ border-right: none;
14
+ }
15
+
16
+ &.checked {
17
+ background-color: var(--mm-primary-color, #26a69a);
18
+ color: var(--mm-button-text, #fff);
19
+ }
20
+ }
21
+ }
22
+
23
+ [data-theme='dark'] {
24
+ .toggle-group {
25
+ border-color: var(--mm-border-color, #555);
26
+
27
+ .toggle-button {
28
+ border-right-color: var(--mm-border-color, #555);
29
+
30
+ &.checked {
31
+ background-color: var(--mm-primary-color, #80cbc4);
32
+ color: var(--mm-button-text, #000);
33
+ }
34
+ }
35
+ }
36
+ }
@@ -53,3 +53,4 @@
53
53
  @use "components/masonry";
54
54
  @use "components/image-list";
55
55
  @use 'components/rating';
56
+ @use 'components/toggle-group';