@juspay/svelte-ui-components 2.118.0 → 2.119.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/Card/Card.svelte +27 -8
- package/dist/Card/properties.d.ts +19 -3
- package/dist/ChipInput/ChipInput.svelte +40 -10
- package/package.json +1 -1
package/dist/Card/Card.svelte
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
classes,
|
|
9
9
|
testId,
|
|
10
10
|
onclick,
|
|
11
|
+
href,
|
|
12
|
+
target,
|
|
13
|
+
rel,
|
|
11
14
|
headerRight,
|
|
12
15
|
footer,
|
|
13
16
|
stretch = false,
|
|
@@ -15,7 +18,14 @@
|
|
|
15
18
|
cssVars
|
|
16
19
|
}: CardProperties = $props();
|
|
17
20
|
|
|
18
|
-
const
|
|
21
|
+
const isAnchor = $derived(typeof href === 'string' && href.length > 0);
|
|
22
|
+
const isInteractive = $derived(isAnchor || typeof onclick === 'function');
|
|
23
|
+
// HTML target values are ASCII case-insensitive (e.g. "_BLANK" opens a new
|
|
24
|
+
// context identically to "_blank"), so the comparison must normalize case
|
|
25
|
+
// to keep the noopener/noreferrer default from being silently skipped.
|
|
26
|
+
const resolvedRel = $derived(
|
|
27
|
+
rel ?? (target?.toLowerCase() === '_blank' ? 'noopener noreferrer' : null)
|
|
28
|
+
);
|
|
19
29
|
|
|
20
30
|
const styleAttr = $derived(
|
|
21
31
|
cssVars
|
|
@@ -37,8 +47,8 @@
|
|
|
37
47
|
};
|
|
38
48
|
</script>
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
<svelte:element
|
|
51
|
+
this={isAnchor ? 'a' : 'div'}
|
|
42
52
|
class="card {classes ?? ''}"
|
|
43
53
|
class:card-interactive={isInteractive}
|
|
44
54
|
class:card-stretch={stretch}
|
|
@@ -46,10 +56,13 @@
|
|
|
46
56
|
style={styleAttr}
|
|
47
57
|
data-pw={typeof testId === 'string' ? testId : null}
|
|
48
58
|
testID={typeof testId === 'string' ? testId : null}
|
|
49
|
-
role={isInteractive ? 'button' : null}
|
|
50
|
-
tabindex={isInteractive ? 0 : null}
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
role={!isAnchor && isInteractive ? 'button' : null}
|
|
60
|
+
tabindex={!isAnchor && isInteractive ? 0 : null}
|
|
61
|
+
href={isAnchor ? href : null}
|
|
62
|
+
target={isAnchor ? target : null}
|
|
63
|
+
rel={isAnchor ? resolvedRel : null}
|
|
64
|
+
onclick={onclick ?? null}
|
|
65
|
+
onkeydown={!isAnchor && isInteractive ? handleKeydown : null}
|
|
53
66
|
>
|
|
54
67
|
{#if (typeof title === 'string' && title.length > 0) || typeof headerRight === 'function'}
|
|
55
68
|
<div class="card-header" class:card-header-split={typeof headerRight === 'function'}>
|
|
@@ -85,10 +98,16 @@
|
|
|
85
98
|
{@render footer()}
|
|
86
99
|
</footer>
|
|
87
100
|
{/if}
|
|
88
|
-
</
|
|
101
|
+
</svelte:element>
|
|
89
102
|
|
|
90
103
|
<style>
|
|
91
104
|
.card {
|
|
105
|
+
/* Explicit so the root's layout doesn't depend on the browser default for
|
|
106
|
+
whichever tag svelte:element renders -- a <div> defaults to block and an
|
|
107
|
+
<a> defaults to inline, and an inline box ignores width/height entirely.
|
|
108
|
+
Pinning both here keeps anchor-mode cards byte-identical to div cards. */
|
|
109
|
+
display: block;
|
|
110
|
+
text-decoration: none;
|
|
92
111
|
background: var(--card-background, inherit);
|
|
93
112
|
border: var(--card-border, 1px solid currentColor);
|
|
94
113
|
border-radius: var(--card-border-radius, var(--radius, 4px));
|
|
@@ -12,12 +12,28 @@ export type OptionalCardProperties = {
|
|
|
12
12
|
/** Renders as `data-pw` on the root element for Playwright test selection. */
|
|
13
13
|
testId?: string;
|
|
14
14
|
/**
|
|
15
|
-
* When provided the root element becomes interactive
|
|
15
|
+
* When provided (and `href` is not) the root element becomes an interactive `<div>`:
|
|
16
16
|
* `role="button"`, `tabindex=0`, and keydown (Enter/Space) triggers the handler.
|
|
17
|
-
* When
|
|
18
|
-
*
|
|
17
|
+
* When `href` is also provided, the root renders as a native `<a>` instead (see
|
|
18
|
+
* `href`) and this synthetic role/tabindex/keydown shim is skipped, since anchor
|
|
19
|
+
* semantics already cover focus and Enter-activation; `onclick` still fires either
|
|
20
|
+
* way. When neither `onclick` nor `href` is provided the root is a plain `<div>`
|
|
21
|
+
* with no interactive attributes, so existing consumers see zero behaviour change.
|
|
19
22
|
*/
|
|
20
23
|
onclick?: (event: MouseEvent) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Render the card root as an `<a>` styled identically, instead of a `<div>`. Use
|
|
26
|
+
* for card-styled links/navigation. When set, the root is natively focusable and
|
|
27
|
+
* Enter-activates, so the `role="button"`/`tabindex`/keydown shim used for a
|
|
28
|
+
* clickable `<div>` (see `onclick`) is not applied. `onclick` (if also provided)
|
|
29
|
+
* still fires alongside navigation. Omitted by default, so existing consumers are
|
|
30
|
+
* unaffected.
|
|
31
|
+
*/
|
|
32
|
+
href?: string;
|
|
33
|
+
/** Anchor target (only applied when `href` is set), e.g. `_blank`. */
|
|
34
|
+
target?: string;
|
|
35
|
+
/** Anchor rel (only applied when `href` is set). Defaults to `noopener noreferrer` when `target="_blank"`. */
|
|
36
|
+
rel?: string;
|
|
21
37
|
/**
|
|
22
38
|
* Snippet rendered at the top-right of the header row, alongside title/description.
|
|
23
39
|
* When omitted the header row is unchanged (title block takes full width).
|
|
@@ -94,13 +94,30 @@
|
|
|
94
94
|
--pill-* and --input-* have not yet been re-declared: reading them in the same declaration
|
|
95
95
|
that sets them would be a custom-property cycle and would compute to invalid. Consumers that
|
|
96
96
|
theme Pill/Input app-wide get chips that match the rest of their UI, instead of the library's
|
|
97
|
-
|
|
97
|
+
own values overriding their theme.
|
|
98
|
+
|
|
99
|
+
Every token that carries the chip's APPEARANCE is captured here — colour, type, spacing and
|
|
100
|
+
shape alike. An app whose Pill is a 14px, 16px-radius chip was still getting 13px and a
|
|
101
|
+
999px pill, because re-declaring a token on the element beats inheriting it no matter which
|
|
102
|
+
property it is; restoring only the colours left the same bug in a less obvious place.
|
|
103
|
+
Tokens the component owns STRUCTURALLY — the draft field's inline padding, margin and
|
|
104
|
+
shadow, and its width/height — deliberately stay fixed, since those position the field among
|
|
105
|
+
the chips rather than describe how it looks. */
|
|
98
106
|
--chip-input-pill-background-default: var(--pill-background, #e0e0e0);
|
|
99
107
|
--chip-input-pill-color-default: var(--pill-color, #333333);
|
|
100
108
|
--chip-input-pill-dismiss-color-default: var(--pill-dismiss-color, currentColor);
|
|
109
|
+
--chip-input-pill-font-size-default: var(--pill-font-size, 13px);
|
|
110
|
+
--chip-input-pill-font-weight-default: var(--pill-font-weight, 500);
|
|
111
|
+
--chip-input-pill-padding-default: var(--pill-padding, 6px 10px);
|
|
112
|
+
--chip-input-pill-border-radius-default: var(--pill-border-radius, 999px);
|
|
113
|
+
--chip-input-pill-border-default: var(--pill-border, none);
|
|
114
|
+
--chip-input-pill-gap-default: var(--pill-gap, 4px);
|
|
115
|
+
--chip-input-pill-dismiss-size-default: var(--pill-dismiss-size, 14px);
|
|
116
|
+
--chip-input-pill-max-width-default: var(--pill-max-width);
|
|
101
117
|
--chip-input-draft-border-default: var(--input-border, 1px solid transparent);
|
|
102
118
|
--chip-input-draft-focus-border-default: var(--input-focus-border, 1px solid transparent);
|
|
103
119
|
--chip-input-draft-radius-default: var(--input-radius, 4px);
|
|
120
|
+
--chip-input-draft-font-size-default: var(--input-font-size, 13px);
|
|
104
121
|
}
|
|
105
122
|
|
|
106
123
|
.chip-input-draft-wrap {
|
|
@@ -108,16 +125,25 @@
|
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
.chip-input :global(.chip-input-pill) {
|
|
111
|
-
--pill-gap: var(--chip-input-pill-gap,
|
|
128
|
+
--pill-gap: var(--chip-input-pill-gap, var(--chip-input-pill-gap-default));
|
|
112
129
|
--pill-background: var(--chip-input-pill-background, var(--chip-input-pill-background-default));
|
|
113
130
|
--pill-color: var(--chip-input-pill-color, var(--chip-input-pill-color-default));
|
|
114
|
-
--pill-font-size: var(--chip-input-pill-font-size,
|
|
115
|
-
--pill-font-weight: var(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
--pill-
|
|
120
|
-
--pill-
|
|
131
|
+
--pill-font-size: var(--chip-input-pill-font-size, var(--chip-input-pill-font-size-default));
|
|
132
|
+
--pill-font-weight: var(
|
|
133
|
+
--chip-input-pill-font-weight,
|
|
134
|
+
var(--chip-input-pill-font-weight-default)
|
|
135
|
+
);
|
|
136
|
+
--pill-padding: var(--chip-input-pill-padding, var(--chip-input-pill-padding-default));
|
|
137
|
+
--pill-border-radius: var(
|
|
138
|
+
--chip-input-pill-border-radius,
|
|
139
|
+
var(--chip-input-pill-border-radius-default)
|
|
140
|
+
);
|
|
141
|
+
--pill-border: var(--chip-input-pill-border, var(--chip-input-pill-border-default));
|
|
142
|
+
--pill-max-width: var(--chip-input-pill-max-width, var(--chip-input-pill-max-width-default));
|
|
143
|
+
--pill-dismiss-size: var(
|
|
144
|
+
--chip-input-pill-dismiss-size,
|
|
145
|
+
var(--chip-input-pill-dismiss-size-default)
|
|
146
|
+
);
|
|
121
147
|
--pill-dismiss-color: var(
|
|
122
148
|
--chip-input-pill-dismiss-color,
|
|
123
149
|
var(--chip-input-pill-dismiss-color-default)
|
|
@@ -133,9 +159,13 @@
|
|
|
133
159
|
--chip-input-draft-focus-border,
|
|
134
160
|
var(--chip-input-draft-focus-border-default)
|
|
135
161
|
);
|
|
162
|
+
--input-font-size: var(--chip-input-draft-font-size, var(--chip-input-draft-font-size-default));
|
|
163
|
+
|
|
164
|
+
/* Structural, not thematic: the draft field sits inline among the chips, so it keeps its own
|
|
165
|
+
tight padding and no margin or shadow regardless of how the app themes Input elsewhere.
|
|
166
|
+
Override them per-instance via --chip-input-draft-* if a layout genuinely needs it. */
|
|
136
167
|
--input-padding: var(--chip-input-draft-padding, 0 2px);
|
|
137
168
|
--input-margin: 0;
|
|
138
|
-
--input-font-size: var(--chip-input-draft-font-size, 13px);
|
|
139
169
|
--input-box-shadow: none;
|
|
140
170
|
}
|
|
141
171
|
</style>
|