@descope-ui/descope-timer 0.0.1 → 0.0.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [0.0.2](https://github.com/descope/web-components-ui/compare/@descope-ui/descope-timer-0.0.1...@descope-ui/descope-timer-0.0.2) (2025-03-13)
6
+
5
7
  ## 0.0.1 (2025-03-11)
6
8
 
7
9
  ### Dependency Updates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope-ui/descope-timer",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "exports": {
5
5
  ".": {
6
6
  "import": "./src/component/index.js"
@@ -15,7 +15,7 @@ import { formatTime } from './helpers';
15
15
 
16
16
  export const componentName = getComponentName('timer');
17
17
 
18
- const observedAttributes = ['seconds', 'hide-icon'];
18
+ const observedAttributes = ['seconds', 'hide-icon', 'paused'];
19
19
 
20
20
  const BaseClass = createBaseClass({
21
21
  componentName,
@@ -73,57 +73,63 @@ class RawTimer extends BaseClass {
73
73
  return Math.max(0, secs);
74
74
  }
75
75
 
76
+ // we use `pause` attribute for allowing preview mode by executing `pause`
77
+ get isPaused() {
78
+ return this.getAttribute('paused') === 'true';
79
+ }
80
+
76
81
  init() {
77
82
  super.init?.();
78
83
 
79
84
  this.#timeRemains = this.seconds;
80
85
  }
81
86
 
82
- start() {
83
- this.dispatchEvent(new CustomEvent('timer-started', { bubbles: true }));
84
-
85
- this.startInterval();
86
- }
87
-
88
- startInterval() {
87
+ startInterval() {
89
88
  const intervalCycle = () => {
89
+ this.#decreaseInterval();
90
+ if (!this.#timeRemains) this.stop();
90
91
  this.#updateDisplay(this.#timeRemains);
91
-
92
- if (!this.#timeRemains) {
93
- this.stop();
94
- } else {
95
- this.#decreaseInterval();
96
- }
97
- }
98
-
99
- intervalCycle();
92
+ };
100
93
 
101
94
  if (this.#timeRemains) {
102
95
  this.#intervalId = setInterval(intervalCycle, DEFAULT_INTERVAL);
96
+ } else {
97
+ this.stop();
103
98
  }
104
99
  }
105
100
 
101
+ stopInterval() {
102
+ clearInterval(this.#intervalId);
103
+ }
104
+
106
105
  #decreaseInterval() {
107
- this.#timeRemains = Math.max(this.#timeRemains - DEFAULT_INTERVAL, 0);
106
+ this.#timeRemains = this.#timeRemains - DEFAULT_INTERVAL;
108
107
  }
109
108
 
110
109
  reset() {
111
110
  this.#timeRemains = this.seconds;
112
- this.start();
111
+ this.#updateDisplay(this.#timeRemains);
112
+
113
+ if (this.isPaused) return;
114
+
115
+ this.dispatchEvent(new CustomEvent('timer-started', { bubbles: true }));
116
+ this.startInterval();
113
117
  }
114
118
 
115
119
  stop() {
116
- this.pause();
120
+ this.stopInterval();
117
121
  this.#timeRemains = 0;
118
122
  this.#updateDisplay(this.#timeRemains);
119
123
  this.dispatchEvent(new CustomEvent('timer-ended', { bubbles: true }));
120
124
  }
121
125
 
122
126
  pause() {
123
- clearInterval(this.#intervalId);
127
+ this.setAttribute('paused', 'true');
128
+ this.stopInterval();
124
129
  }
125
130
 
126
131
  resume() {
132
+ this.removeAttribute('paused');
127
133
  this.startInterval();
128
134
  }
129
135
 
@@ -135,6 +141,19 @@ class RawTimer extends BaseClass {
135
141
  this.icon.classList.toggle('hidden', val === 'true');
136
142
  }
137
143
 
144
+ #handlePause(paused) {
145
+ setTimeout(() => {
146
+ if (paused) {
147
+ this.pause();
148
+ } else {
149
+ // we want to prevent a another interval from starting in case previous interval was not yet cleared
150
+ if (!this.#intervalId) {
151
+ this.resume();
152
+ }
153
+ }
154
+ });
155
+ }
156
+
138
157
  attributeChangedCallback(attrName, oldValue, newValue) {
139
158
  super.attributeChangedCallback?.(attrName, oldValue, newValue);
140
159
 
@@ -145,28 +164,31 @@ class RawTimer extends BaseClass {
145
164
  if (attrName === 'hide-icon') {
146
165
  this.#toggleIcon(newValue);
147
166
  }
167
+ if (attrName === 'paused') {
168
+ this.#handlePause(newValue === 'true');
169
+ }
148
170
  }
149
171
  }
150
172
  }
151
173
 
152
174
  const { host, icon, timer } = {
153
175
  host: { selector: () => ':host' },
154
- icon: { selector: '.icon' },
155
- timer: { selector: '.timer' },
176
+ icon: { selector: () => '.icon' },
177
+ timer: { selector: () => '.timer' },
156
178
  };
157
179
 
158
180
  export const TimerClass = compose(
159
181
  createStyleMixin({
160
182
  mappings: {
161
- backgroundColor: {},
162
- fontSize: [{}, { ...icon }],
183
+ fontSize: {},
163
184
  iconSize: [
164
185
  { ...icon, property: 'width' },
165
186
  { ...icon, property: 'height' },
166
187
  ],
167
188
  fontFamily: {},
189
+ minHeight: {},
168
190
  fontWeight: { ...timer },
169
- lineHeight: { property: 'min-height' },
191
+ lineHeight: { ...timer },
170
192
  textColor: { ...timer, property: 'color' },
171
193
  gap: {},
172
194
  textAlign: { property: 'justify-content' },
@@ -1,4 +1,4 @@
1
- <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M6 0C2.7 0 0 2.7 0 6C0 9.3 2.7 12 6 12C9.3 12 12 9.3 12 6C12 2.7 9.3 0 6 0ZM6 10.5C3.525 10.5 1.5 8.475 1.5 6C1.5 3.525 3.525 1.5 6 1.5C8.475 1.5 10.5 3.525 10.5 6C10.5 8.475 8.475 10.5 6 10.5Z" fill="#181A1C"/>
3
- <path d="M6 2.25H5.25V6.75H9V6H6V2.25Z" fill="#181A1C"/>
1
+ <svg width="1em" height="1em" viewBox="0 0 101 101" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M50.3334 0.333252C22.8334 0.333252 0.333374 22.8333 0.333374 50.3333C0.333374 77.8333 22.8334 100.333 50.3334 100.333C77.8334 100.333 100.333 77.8333 100.333 50.3333C100.333 22.8333 77.8334 0.333252 50.3334 0.333252ZM50.3334 87.8333C29.7084 87.8333 12.8334 70.9583 12.8334 50.3333C12.8334 29.7083 29.7084 12.8333 50.3334 12.8333C70.9584 12.8333 87.8334 29.7083 87.8334 50.3333C87.8334 70.9583 70.9584 87.8333 50.3334 87.8333Z" fill="#181A1C"/>
3
+ <path d="M50.3328 19.0833H44.0828V56.5832H75.3328V50.3332H50.3328V19.0833Z" fill="#181A1C"/>
4
4
  </svg>
package/src/theme.js CHANGED
@@ -9,7 +9,8 @@ const timer = {
9
9
  [vars.hostDirection]: globalRefs.direction,
10
10
  [vars.gap]: '0.25em',
11
11
  [vars.fontFamily]: globalRefs.fonts.font1.family,
12
- [vars.lineHeight]: '2em',
12
+ [vars.minHeight]: '1.5em',
13
+ [vars.lineHeight]: '1em',
13
14
  [vars.fontWeight]: globalRefs.fonts.font1.fontWeight,
14
15
  [vars.textColor]: globalRefs.colors.surface.contrast,
15
16
  [vars.iconColor]: globalRefs.colors.surface.contrast,
@@ -13,6 +13,7 @@ const Template = ({
13
13
  'hide-icon': hideIcon,
14
14
  'full-width': fullWidth,
15
15
  'text-align': textAlign,
16
+ pause,
16
17
  }) => `
17
18
  <descope-timer
18
19
  seconds="${seconds}"
@@ -20,6 +21,7 @@ const Template = ({
20
21
  hide-icon="${hideIcon || false}"
21
22
  full-width="${fullWidth}"
22
23
  text-align="${textAlign}"
24
+ pause="${pause || false}"
23
25
  st-host-direction="${direction ?? ''}"
24
26
  ></descope-timer>
25
27
  `;
@@ -59,6 +61,12 @@ export default {
59
61
  type: 'boolean',
60
62
  },
61
63
  },
64
+ pause: {
65
+ name: 'Pause',
66
+ control: {
67
+ type: 'boolean',
68
+ },
69
+ },
62
70
  },
63
71
  };
64
72