polymorph-ui-components 0.5.0 → 0.6.2

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.
@@ -102,6 +102,8 @@
102
102
  gap: var(--button-content-gap, 16px);
103
103
  visibility: var(--button-visibility, visible);
104
104
  box-shadow: var(--button-box-shadow, none);
105
+ text-decoration: var(--button-text-decoration, none);
106
+ line-height: var(--button-line-height, normal);
105
107
  }
106
108
 
107
109
  .disabled {
@@ -112,6 +114,7 @@
112
114
  font-weight: var(--button-disabled-font-weight);
113
115
  border: var(--button-disabled-border);
114
116
  background: var(--button-disabled-background-color, var(--button-color, #18181b));
117
+ text-decoration: var(--button-disabled-text-decoration, var(--button-text-decoration, none));
115
118
  }
116
119
 
117
120
  .button-loader {
@@ -133,6 +136,7 @@
133
136
  color: var(--button-hover-text-color, var(--button-text-color, #ffffff));
134
137
  border: var(--button-hover-border, var(--button-border, none));
135
138
  transform: var(--button-hover-transform);
139
+ opacity: var(--button-hover-opacity, var(--button-opacity, 1));
136
140
  }
137
141
 
138
142
  button:active {
@@ -30,6 +30,7 @@
30
30
  headerActions,
31
31
  headerContent,
32
32
  message,
33
+ messageAttachments,
33
34
  empty,
34
35
  composerLeading,
35
36
  sendIcon,
@@ -83,7 +84,16 @@
83
84
  />
84
85
  {/if}
85
86
 
86
- <ChatMessageList {messages} {autoscroll} {message} {empty} {allowCopy} {onretry} {onfeedback} />
87
+ <ChatMessageList
88
+ {messages}
89
+ {autoscroll}
90
+ {message}
91
+ {messageAttachments}
92
+ {empty}
93
+ {allowCopy}
94
+ {onretry}
95
+ {onfeedback}
96
+ />
87
97
 
88
98
  <div class="footer">
89
99
  {#if showSuggestions}
@@ -29,6 +29,7 @@ export type OptionalChatProperties = {
29
29
  headerActions?: Snippet;
30
30
  headerContent?: Snippet;
31
31
  message?: Snippet<[ChatMessageData]>;
32
+ messageAttachments?: Snippet<[ChatMessageData]>;
32
33
  empty?: Snippet;
33
34
  composerLeading?: Snippet;
34
35
  sendIcon?: Snippet;
@@ -252,6 +252,10 @@
252
252
  margin: var(--chat-message-attachments-margin, 4px 0 0 0);
253
253
  }
254
254
 
255
+ .message-attachments:empty {
256
+ display: none;
257
+ }
258
+
255
259
  .actions {
256
260
  display: flex;
257
261
  align-items: center;
@@ -12,7 +12,7 @@ export type OptionalChatMessageProperties = {
12
12
  status?: ChatMessageStatus;
13
13
  avatar?: Snippet;
14
14
  header?: Snippet;
15
- attachments?: Snippet;
15
+ attachments?: Snippet | null;
16
16
  allowCopy?: boolean;
17
17
  actions?: Snippet;
18
18
  copyLabel?: string;
@@ -14,6 +14,7 @@
14
14
  messages,
15
15
  autoscroll = true,
16
16
  message,
17
+ messageAttachments,
17
18
  empty,
18
19
  jumpLabel = 'Jump to latest',
19
20
  jumpIcon,
@@ -105,6 +106,9 @@
105
106
  {#if typeof message === 'function'}
106
107
  {@render message(msg)}
107
108
  {:else}
109
+ {#snippet attachmentsFor()}
110
+ {@render messageAttachments?.(msg)}
111
+ {/snippet}
108
112
  <ChatMessage
109
113
  role={msg.role}
110
114
  content={msg.content}
@@ -112,6 +116,7 @@
112
116
  streaming={msg.streaming}
113
117
  status={msg.status}
114
118
  allowCopy={allowCopy && partyOf(msg.role) === 'responder'}
119
+ attachments={typeof messageAttachments === 'function' ? attachmentsFor : null}
115
120
  onretry={retryFor(msg)}
116
121
  onfeedback={feedbackFor(msg)}
117
122
  />
@@ -8,6 +8,7 @@ export type MandatoryChatMessageListProperties = {
8
8
  export type OptionalChatMessageListProperties = {
9
9
  autoscroll?: boolean;
10
10
  message?: Snippet<[ChatMessageData]>;
11
+ messageAttachments?: Snippet<[ChatMessageData]>;
11
12
  empty?: Snippet;
12
13
  jumpLabel?: string;
13
14
  jumpIcon?: Snippet;
@@ -1,10 +1,12 @@
1
1
  <script lang="ts">
2
2
  import type { ChoiceboxProperties } from './properties';
3
+ import checkmarkSvg from '../assets/checkmark.svg?raw';
3
4
 
4
5
  let {
5
6
  children,
6
7
  selected = $bindable(false),
7
8
  mode = 'radio',
9
+ showIndicator = false,
8
10
  disabled = false,
9
11
  testId,
10
12
  onclick,
@@ -43,8 +45,18 @@
43
45
  onkeydown={handleKeyDown}
44
46
  data-pw={testId}
45
47
  >
46
- {#if typeof children === 'function'}
47
- {@render children()}
48
+ <div class="body">
49
+ {#if typeof children === 'function'}
50
+ {@render children()}
51
+ {/if}
52
+ </div>
53
+ {#if showIndicator}
54
+ <span class="indicator {mode}" class:selected aria-hidden="true">
55
+ {#if mode === 'checkbox' && selected}
56
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -->
57
+ <span class="indicator-icon">{@html checkmarkSvg}</span>
58
+ {/if}
59
+ </span>
48
60
  {/if}
49
61
  </div>
50
62
 
@@ -63,6 +75,14 @@
63
75
  -webkit-tap-highlight-color: transparent;
64
76
  }
65
77
 
78
+ .body {
79
+ flex: var(--choicebox-body-flex, 1);
80
+ min-width: var(--choicebox-body-min-width, 0);
81
+ display: var(--choicebox-body-display, flex);
82
+ align-items: var(--choicebox-body-align-items, var(--choicebox-align-items, center));
83
+ gap: var(--choicebox-body-gap, var(--choicebox-gap, 12px));
84
+ }
85
+
66
86
  .choicebox:focus-visible {
67
87
  outline: none;
68
88
  box-shadow: var(--choicebox-focus-ring, 0 0 0 3px currentColor);
@@ -82,4 +102,46 @@
82
102
  opacity: var(--choicebox-disabled-opacity, 0.4);
83
103
  cursor: var(--choicebox-disabled-cursor, not-allowed);
84
104
  }
105
+
106
+ .indicator {
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ box-sizing: border-box;
111
+ width: var(--choicebox-indicator-size, 20px);
112
+ height: var(--choicebox-indicator-size, 20px);
113
+ border: var(--choicebox-indicator-border, 2px solid #757575);
114
+ background: var(--choicebox-indicator-background, transparent);
115
+ transition: var(--choicebox-indicator-transition, background 0.2s, border-color 0.2s);
116
+ }
117
+
118
+ .indicator.radio {
119
+ border-radius: 50%;
120
+ }
121
+
122
+ .indicator.checkbox {
123
+ border-radius: var(--choicebox-indicator-border-radius, var(--radius, 4px));
124
+ }
125
+
126
+ .indicator.selected {
127
+ border: var(--choicebox-indicator-selected-border, 2px solid #2196f3);
128
+ background: var(--choicebox-indicator-selected-background, #2196f3);
129
+ }
130
+
131
+ .indicator.radio.selected {
132
+ box-shadow: inset 0 0 0 var(--choicebox-indicator-dot-inset, 4px)
133
+ var(--choicebox-indicator-dot-color, #ffffff);
134
+ }
135
+
136
+ .indicator-icon {
137
+ display: flex;
138
+ width: var(--choicebox-indicator-icon-size, 14px);
139
+ height: var(--choicebox-indicator-icon-size, 14px);
140
+ color: var(--choicebox-indicator-icon-color, #ffffff);
141
+ }
142
+
143
+ .indicator-icon :global(svg) {
144
+ width: 100%;
145
+ height: 100%;
146
+ }
85
147
  </style>
@@ -6,6 +6,7 @@ export type OptionalChoiceboxProperties = {
6
6
  selected?: boolean;
7
7
  mode?: ChoiceboxMode;
8
8
  disabled?: boolean;
9
+ showIndicator?: boolean;
9
10
  testId?: string;
10
11
  classes?: string;
11
12
  };
@@ -8,11 +8,14 @@
8
8
 
9
9
  let overlayDiv: HTMLDivElement | null = $state(null);
10
10
  let backPressed = false;
11
+ let dismissTimer: ReturnType<typeof setTimeout> | null = null;
11
12
 
12
13
  let {
13
14
  size = 'fit-content',
14
15
  align = 'center',
15
16
  showOverlay = true,
17
+ lockScroll = true,
18
+ autoDismissAfter = null,
16
19
  supportHardwareBackPress = false,
17
20
  enableTransition = true,
18
21
  transitionType = 'ALL',
@@ -75,7 +78,12 @@
75
78
  }
76
79
 
77
80
  onMount(() => {
78
- document.body.style.overflow = 'hidden';
81
+ if (lockScroll) {
82
+ document.body.style.overflow = 'hidden';
83
+ }
84
+ if (typeof autoDismissAfter === 'number') {
85
+ dismissTimer = setTimeout(() => onclose?.(), autoDismissAfter);
86
+ }
79
87
  if (supportHardwareBackPress) {
80
88
  history.pushState(null, '', window.location.href);
81
89
  window.addEventListener('popstate', handlePopstate);
@@ -83,8 +91,13 @@
83
91
  });
84
92
 
85
93
  onDestroy(() => {
94
+ if (dismissTimer !== null) {
95
+ clearTimeout(dismissTimer);
96
+ }
86
97
  if (typeof window !== 'undefined') {
87
- document.body.style.overflow = '';
98
+ if (lockScroll) {
99
+ document.body.style.overflow = '';
100
+ }
88
101
  if (supportHardwareBackPress) {
89
102
  if (!backPressed) {
90
103
  history.back();
@@ -172,7 +185,7 @@
172
185
 
173
186
  <style>
174
187
  .modal {
175
- position: fixed;
188
+ position: var(--modal-position, fixed);
176
189
  top: 0;
177
190
  bottom: 0;
178
191
  left: 0;
@@ -7,6 +7,8 @@ export type ModalProperties = ModalEventProperties & {
7
7
  size?: ModalSize;
8
8
  align?: ModalAlign;
9
9
  showOverlay?: boolean;
10
+ lockScroll?: boolean;
11
+ autoDismissAfter?: number | null;
10
12
  supportHardwareBackPress?: boolean;
11
13
  enableTransition?: boolean;
12
14
  transitionType?: ModalTransition;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polymorph-ui-components",
3
- "version": "0.5.0",
3
+ "version": "0.6.2",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",
@@ -14,6 +14,15 @@
14
14
  "svelte-components"
15
15
  ],
16
16
  "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/sinha-sahil/polymorph-ui-components.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/sinha-sahil/polymorph-ui-components/issues"
23
+ },
24
+ "homepage": "https://github.com/sinha-sahil/polymorph-ui-components#readme",
25
+ "author": "Sahil Sinha",
17
26
  "scripts": {
18
27
  "prepare": "husky",
19
28
  "dev": "vite dev --host",