diff --git a/package-lock.json b/package-lock.json
index 03a2fd48..a8c548e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "fold-dev",
- "version": "0.3.0",
+ "version": "0.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "fold-dev",
- "version": "0.3.0",
+ "version": "0.4.0",
"license": "ISC",
"devDependencies": {
"@babel/preset-env": "^7.21.5",
@@ -23247,7 +23247,7 @@
},
"packages/core": {
"name": "@fold-dev/core",
- "version": "0.3.0",
+ "version": "0.4.0",
"license": "MIT",
"dependencies": {
"react": "^18.2.0",
@@ -23663,7 +23663,7 @@
},
"packages/design": {
"name": "@fold-dev/design",
- "version": "0.3.0",
+ "version": "0.4.0",
"license": "MIT",
"devDependencies": {
"nodemon": "^2.0.20",
diff --git a/package.json b/package.json
index a4332edd..f483a044 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "fold-dev",
"title": "Fold",
- "version": "0.3.0",
+ "version": "0.4.0",
"description": "The UI library for product teams.",
"workspaces": {
"packages": [
diff --git a/packages/core/package.json b/packages/core/package.json
index 41aea83c..534fad95 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,7 +1,7 @@
{
"name": "@fold-dev/core",
"title": "Fold",
- "version": "0.3.0",
+ "version": "0.4.0",
"description": "The UI library for product teams.",
"main": "dist/index.js",
"module": "dist/index.js",
diff --git a/packages/core/src/button/button.css b/packages/core/src/button/button.css
index 6f2d92f4..a2f7e82a 100644
--- a/packages/core/src/button/button.css
+++ b/packages/core/src/button/button.css
@@ -472,17 +472,20 @@
width: 100%;
}
-.f-button-group.is-vertical > .f-button:not(.f-button:first-of-type):not(.f-button:last-of-type) {
+.f-button-group.is-vertical > .f-button:not(.f-button:first-of-type):not(.f-button:last-of-type),
+.f-button-group.is-vertical > .f-button:not(.f-button:first-of-type):not(.f-button:last-of-type)::after {
border-radius: 0px;
border-bottom: 0px;
}
-.f-button-group.is-vertical > .f-button:last-of-type:not(.f-button:first-of-type) {
+.f-button-group.is-vertical > .f-button:last-of-type:not(.f-button:first-of-type),
+.f-button-group.is-vertical > .f-button:last-of-type:not(.f-button:first-of-type)::after {
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
-.f-button-group.is-vertical > .f-button:first-of-type:not(.f-button:last-of-type) {
+.f-button-group.is-vertical > .f-button:first-of-type:not(.f-button:last-of-type),
+.f-button-group.is-vertical > .f-button:first-of-type:not(.f-button:last-of-type)::after {
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
border-bottom: 0px;
@@ -490,18 +493,51 @@
/* horizontal */
-.f-button-group.is-horizontal > .f-button:not(.f-button:first-of-type):not(.f-button:last-of-type) {
+.f-button-group.is-horizontal > .f-button:not(.f-button:first-of-type):not(.f-button:last-of-type),
+.f-button-group.is-horizontal > .f-button:not(.f-button:first-of-type):not(.f-button:last-of-type)::after {
border-radius: 0px;
border-right: 0px;
}
-.f-button-group.is-horizontal > .f-button:last-of-type:not(.f-button:first-of-type) {
+.f-button-group.is-horizontal > .f-button:last-of-type:not(.f-button:first-of-type),
+.f-button-group.is-horizontal > .f-button:last-of-type:not(.f-button:first-of-type)::after {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
-.f-button-group.is-horizontal > .f-button:first-of-type:not(.f-button:last-of-type) {
+.f-button-group.is-horizontal > .f-button:first-of-type:not(.f-button:last-of-type),
+.f-button-group.is-horizontal > .f-button:first-of-type:not(.f-button:last-of-type)::after {
border-bottom-right-radius: 0px;
border-top-right-radius: 0px;
border-right: 0px;
}
+
+/* colors */
+
+.f-button-group .f-button.is-accent:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-accent-weak);
+}
+
+.f-button-group .f-button.is-success:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-success-weak);
+}
+
+.f-button-group .f-button.is-neutral:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-neutral-weak);
+}
+
+.f-button-group .f-button.is-caution:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-caution-weak);
+}
+
+.f-button-group .f-button.is-warning:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-warning-weak);
+}
+
+.f-button-group .f-button.is-danger:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-danger-weak);
+}
+
+.f-button-group .f-button.is-highlight:not(.is-subtle):not(.is-outline) {
+ border-color: var(--f-color-highlight-weak);
+}
diff --git a/packages/core/src/button/button.stories.tsx b/packages/core/src/button/button.stories.tsx
index 5dd2d4bc..fd44d6a9 100644
--- a/packages/core/src/button/button.stories.tsx
+++ b/packages/core/src/button/button.stories.tsx
@@ -252,13 +252,19 @@ export const States = () => (
export const AsLink = () => (
+
)
diff --git a/packages/core/src/drag/drag.css b/packages/core/src/drag/drag.css
index cb61432b..56153ee4 100644
--- a/packages/core/src/drag/drag.css
+++ b/packages/core/src/drag/drag.css
@@ -85,6 +85,12 @@
in the parent DragElementArea (.f-drag-area)
*/
+:root {
+ --f-drag-lined-x-offset: -50%;
+ --f-drag-lined-y-offset: -50%;
+ --f-drag-lined-size: 3px;
+}
+
.f-drag-area__element__line {
position: absolute;
background: var(--f-color-accent);
@@ -96,28 +102,36 @@
top: 0px;
left: 0px;
width: 100%;
- height: 0.25rem;
+ height: var(--f-drag-lined-size);
}
.f-drag-area__element__line.is-vertical.is-last {
bottom: 0;
left: 0;
width: 100%;
- height: 0.25rem;
+ height: var(--f-drag-lined-size);
}
.f-drag-area__element__line.is-horizontal.is-first {
left: 0;
top: 0;
height: 100%;
- width: 0.25rem;
+ width: var(--f-drag-lined-size);
}
.f-drag-area__element__line.is-horizontal.is-last {
right: 0;
top: 0;
height: 100%;
- width: 0.25rem;
+ width: var(--f-drag-lined-size);
+}
+
+.f-drag-area__element__line.is-horizontal {
+ transform: translateX(var(--f-drag-lined-x-offset));
+}
+
+.f-drag-area__element__line.is-vertical {
+ transform: translateY(var(--f-drag-lined-y-offset));
}
/* lined-focus variant */
@@ -168,7 +182,7 @@
position: absolute;
top: 0px;
left: 0px;
- height: 0.25rem;
+ height: var(--f-drag-lined-size);
pointer-events: none;
z-index: 10000;
background: var(--f-color-accent);
@@ -176,13 +190,25 @@
transition: transform 0.05s var(--f-drag-transition);
}
+:root {
+ --f-drag-placeholder-background: var(--f-color-surface-stronger);
+ --f-drag-placeholder-radius: 0;
+ --f-drag-placeholder-border: none;
+ --f-drag-placeholder-outline: none;
+ --f-drag-placeholder-margin: 0;
+}
+
.f-drag-area__placeholder {
position: absolute;
top: 0px;
left: 0px;
pointer-events: none;
z-index: 1;
- background: var(--f-color-surface-stronger);
+ margin: var(--f-drag-placeholder-margin);
+ border: var(--f-drag-placeholder-border);
+ outline: var(--f-drag-placeholder-outline);
+ border-radius: var(--f-drag-placeholder-radius);
+ background: var(--f-drag-placeholder-background);
/* animation: f-drag-fadein var(--f-transition-duration-fast); */
/* transition: transform 0.1s var(--f-drag-transition); */
/* background: red; */
diff --git a/packages/core/src/drag/drag.tsx b/packages/core/src/drag/drag.tsx
index 99082b08..9cb8ac31 100644
--- a/packages/core/src/drag/drag.tsx
+++ b/packages/core/src/drag/drag.tsx
@@ -512,7 +512,7 @@ export const DragManager = (props: DragManagerProps) => {
nextIndent,
}
- // debug
+ // outline the previous & next elements
// for (let target of element.parentNode.children) target.style.border = 'none'
// if (previous) previous.style.border = '0.2rem solid crimson'
// if (next) next.style.border = '0.2rem solid darkcyan'
diff --git a/packages/core/src/input/input.css b/packages/core/src/input/input.css
index c1ef3507..079ec6cf 100644
--- a/packages/core/src/input/input.css
+++ b/packages/core/src/input/input.css
@@ -8,13 +8,14 @@
--f-input-color-placeholder: var(--f-color-text-weakest);
--f-input-color-disabled: var(--f-color-text-weakest);
--f-input-border-radius: var(--f-radius);
- --f-input-padding: 0 var(--f-space-4);
+ --f-input-base-padding: var(--f-space-4);
+ --f-input-padding: 0 var(--f-input-base-padding);
--f-input-padding-combo: var(--f-space-1) var(--f-space-2);
--f-input-shadow: var(--f-shadow-sm);
--f-combo-input-min-width: 50px;
--f-combo-input-spacing: var(--f-space-1);
- --f-input-prefix-padding: 0 0 0 var(--f-space-4);
- --f-input-suffix-padding: 0 var(--f-space-4) 0 0;
+ --f-input-prefix-padding: 0 0 0 var(--f-input-base-padding);
+ --f-input-suffix-padding: 0 var(--f-input-base-padding) 0 0;
}
/* control */
@@ -399,11 +400,29 @@ input.f-input[type=color].xl {
justify-content: stretch;
align-items: stretch;
align-content: stretch;
- height: 100%;
border: var(--f-input-border-width) solid var(--f-input-border-color);
+}
+
+.f-input-number-control.xs {
+ height: var(--f-size-8);
+}
+.f-input-number-control.sm {
+ height: var(--f-size-9);
}
+.f-input-number-control.md {
+ height: var(--f-size-11);
+}
+
+.f-input-number-control.lg {
+ height: var(--f-size-13);
+}
+
+.f-input-number-control.xl {
+ height: var(--f-size-15);
+}
+
.f-input-prefix .f-input-number-control,
.f-input-suffix .f-input-number-control {
border: none;
@@ -412,12 +431,12 @@ input.f-input[type=color].xl {
.f-input-prefix .f-input-number-control {
border-right: var(--f-input-border-width) solid var(--f-input-border-color);
- margin-left: calc((var(--f-space-3) * -1) + var(--f-input-border-width));
+ margin-left: calc(var(--f-input-base-padding) * -1);
}
.f-input-suffix .f-input-number-control {
border-left: var(--f-input-border-width) solid var(--f-input-border-color);
- margin-right: calc((var(--f-space-3) * -1) + var(--f-input-border-width));
+ margin-right: calc(var(--f-input-base-padding) * -1);
}
/* they always need to be the first or last element */
diff --git a/packages/core/src/input/input.tsx b/packages/core/src/input/input.tsx
index e31fc3e3..99d06e98 100644
--- a/packages/core/src/input/input.tsx
+++ b/packages/core/src/input/input.tsx
@@ -30,7 +30,7 @@ export const InputNumberControl = (props: InputNumberControlProps) => {
className={className}>
{
* {
+.f-progress-subtle > * {
z-index: 1;
position: relative;
}
-.f-subtle-progress__bar {
+.f-progress-subtle__bar {
z-index: 0;
border-radius: var(--f-progress-radius);
top: 0px;
@@ -128,41 +128,41 @@
pointer-events: none;
}
-.f-subtle-progress.is-accent .f-subtle-progress__bar,
-.f-subtle-progress.is-success .f-subtle-progress__bar,
-.f-subtle-progress.is-neutral .f-subtle-progress__bar,
-.f-subtle-progress.is-caution .f-subtle-progress__bar,
-.f-subtle-progress.is-warning .f-subtle-progress__bar,
-.f-subtle-progress.is-danger .f-subtle-progress__bar,
-.f-subtle-progress.is-highlight .f-subtle-progress__bar {
- opacity: var(--f-subtle-progress-opacity);
+.f-progress-subtle.is-accent .f-progress-subtle__bar,
+.f-progress-subtle.is-success .f-progress-subtle__bar,
+.f-progress-subtle.is-neutral .f-progress-subtle__bar,
+.f-progress-subtle.is-caution .f-progress-subtle__bar,
+.f-progress-subtle.is-warning .f-progress-subtle__bar,
+.f-progress-subtle.is-danger .f-progress-subtle__bar,
+.f-progress-subtle.is-highlight .f-progress-subtle__bar {
+ opacity: var(--f-progress-subtle-opacity);
}
-.f-subtle-progress.is-accent .f-subtle-progress__bar {
+.f-progress-subtle.is-accent .f-progress-subtle__bar {
background: var(--f-color-accent);
}
-.f-subtle-progress.is-success .f-subtle-progress__bar {
+.f-progress-subtle.is-success .f-progress-subtle__bar {
background: var(--f-color-success);
}
-.f-subtle-progress.is-neutral .f-subtle-progress__bar {
+.f-progress-subtle.is-neutral .f-progress-subtle__bar {
background: var(--f-color-neutral);
}
-.f-subtle-progress.is-caution .f-subtle-progress__bar {
+.f-progress-subtle.is-caution .f-progress-subtle__bar {
background: var(--f-color-caution);
}
-.f-subtle-progress.is-warning .f-subtle-progress__bar {
+.f-progress-subtle.is-warning .f-progress-subtle__bar {
background: var(--f-color-warning);
}
-.f-subtle-progress.is-danger .f-subtle-progress__bar {
+.f-progress-subtle.is-danger .f-progress-subtle__bar {
background: var(--f-color-danger);
}
-.f-subtle-progress.is-highlight .f-subtle-progress__bar {
+.f-progress-subtle.is-highlight .f-progress-subtle__bar {
background: var(--f-color-highlight);
}
@@ -204,26 +204,26 @@
/* circular */
-.f-circular-progress {
+.f-progress-circle {
position: relative;
}
-.f-circular-progress svg {
+.f-progress-circle svg {
transform: rotateZ(-90deg);
}
-.f-circular-progress circle {
+.f-progress-circle circle {
stroke-dashoffset: 0;
transition: stroke-dashoffset 1s linear;
stroke: var(--f-progress-background);
stroke-width: 1rem;
}
-.f-circular-progress circle:last-of-type {
+.f-progress-circle circle:last-of-type {
stroke: var(--f-progress-active);
}
-.f-circular-progress-children {
+.f-progress-circle-children {
position: absolute;
top: 0px;
left: 0px;
@@ -232,32 +232,96 @@
text-align: center;
}
-.f-circular-progress.is-accent circle:last-of-type {
+.f-progress-circle.is-accent circle:last-of-type {
stroke: var(--f-color-accent);
}
-.f-circular-progress.is-success circle:last-of-type {
+.f-progress-circle.is-success circle:last-of-type {
stroke: var(--f-color-success);
}
-.f-circular-progress.is-neutral circle:last-of-type {
+.f-progress-circle.is-neutral circle:last-of-type {
stroke: var(--f-color-neutral);
}
-.f-circular-progress.is-caution circle:last-of-type {
+.f-progress-circle.is-caution circle:last-of-type {
stroke: var(--f-color-caution);
}
-.f-circular-progress.is-warning circle:last-of-type {
+.f-progress-circle.is-warning circle:last-of-type {
stroke: var(--f-color-warning);
}
-.f-circular-progress.is-danger circle:last-of-type {
+.f-progress-circle.is-danger circle:last-of-type {
stroke: var(--f-color-danger);
}
-.f-circular-progress.is-highlight circle:last-of-type {
+.f-progress-circle.is-highlight circle:last-of-type {
stroke: var(--f-color-highlight);
}
+/* progress pie */
+.f-progress-pie .f-progress-pie__background {
+ fill: var(--f-progress-background);
+}
+
+.f-progress-pie .f-progress-pie__fill {
+ fill: var(--f-progress-active);
+}
+
+.f-progress-pie.is-accent .f-progress-pie__background {
+ fill: var(--f-color-accent-weak);
+}
+
+.f-progress-pie.is-accent .f-progress-pie__fill {
+ fill: var(--f-color-accent);
+}
+
+.f-progress-pie.is-success .f-progress-pie__background {
+ fill: var(--f-color-success-weak);
+}
+
+.f-progress-pie.is-success .f-progress-pie__fill {
+ fill: var(--f-color-success);
+}
+
+.f-progress-pie.is-neutral .f-progress-pie__background {
+ fill: var(--f-color-neutral-weak);
+}
+
+.f-progress-pie.is-neutral .f-progress-pie__fill {
+ fill: var(--f-color-neutral);
+}
+
+.f-progress-pie.is-caution .f-progress-pie__background {
+ fill: var(--f-color-caution-weak);
+}
+
+.f-progress-pie.is-caution .f-progress-pie__fill {
+ fill: var(--f-color-caution);
+}
+
+.f-progress-pie.is-warning .f-progress-pie__background {
+ fill: var(--f-color-warning-weak);
+}
+
+.f-progress-pie.is-warning .f-progress-pie__fill {
+ fill: var(--f-color-warning);
+}
+
+.f-progress-pie.is-danger .f-progress-pie__background {
+ fill: var(--f-color-danger-weak);
+}
+
+.f-progress-pie.is-danger .f-progress-pie__fill {
+ fill: var(--f-color-danger);
+}
+
+.f-progress-pie.is-highlight .f-progress-pie__background {
+ fill: var(--f-color-highlight-weak);
+}
+
+.f-progress-pie.is-highlight .f-progress-pie__fill {
+ fill: var(--f-color-highlight);
+}
diff --git a/packages/core/src/progress/progress.stories.tsx b/packages/core/src/progress/progress.stories.tsx
index 13a54725..4fba73bd 100644
--- a/packages/core/src/progress/progress.stories.tsx
+++ b/packages/core/src/progress/progress.stories.tsx
@@ -1,4 +1,4 @@
-import { CircularProgress, Heading, Progress, Stack, SubtleProgress, Text } from '@fold-dev/core'
+import { ProgressCircle, Heading, Progress, Stack, ProgressSubtle, Text, ProgressPie } from '@fold-dev/core'
import React from 'react'
export default {
@@ -155,49 +155,49 @@ export const States = () => (
// --
-export const Circular = () => (
+export const Circle = () => (
-
+ thickness={20}>
20%
-
-
+
-
-
-
-
- (
// --
+export const Pie = () => (
+
+
+
+
+
+
+
+
+
+
+)
+
+// --
+
export const Subtle = () => (
-
+
Redux
-
+
-
MobX
-
+
-
Zustand
-
+
)
diff --git a/packages/core/src/progress/progress.tsx b/packages/core/src/progress/progress.tsx
index a783c3ab..e60d11a8 100644
--- a/packages/core/src/progress/progress.tsx
+++ b/packages/core/src/progress/progress.tsx
@@ -1,5 +1,5 @@
import { classNames, getActionClass } from '../helpers'
-import React from 'react'
+import React, { useMemo } from 'react'
import { View } from '..'
import { CommonProps, CoreViewProps, Variant } from '../types'
@@ -41,26 +41,32 @@ export const Progress = (props: ProgressProps) => {
)
}
-export type CircularProgressProps = {
+export type ProgressCircleProps = {
value: number
thickness?: number
size?: number
variant?: Variant
} & CoreViewProps
-export const CircularProgress = (props: CircularProgressProps) => {
- const { value = 0, thickness = '1rem', size = 50, variant = 'default', ...rest } = props
+export const ProgressCircle = (props: ProgressCircleProps) => {
+ const {
+ value = 0,
+ thickness = '1rem',
+ size = 50,
+ variant = 'default',
+ ...rest
+ } = props
const radius = 90
const circ = Math.PI * (radius * 2)
const pct = ((100 - value) / 100) * circ
const className = classNames(
{
- 'f-circular-progress': true,
+ 'f-progress-circle': true,
'f-row': true,
},
[props.className, getActionClass(variant)]
)
-
+
return (
{
fill="transparent"
strokeDasharray="565.48"
strokeDashoffset="0"
- style={{ strokeWidth: thickness }}>
+ style={{ strokeWidth: thickness }}
+ />
{
strokeDasharray="565.48"
strokeDashoffset={0}
style={{ strokeWidth: thickness, strokeDashoffset: pct }}
- strokeLinecap="butt">
+ strokeLinecap="butt"
+ />
+
+ {!!props.children && {props.children}
}
+
+ )
+}
+
+export type ProgressPieProps = {
+ value: number
+ padding?: number
+ size?: number
+ variant?: Variant
+} & CoreViewProps
+
+export const ProgressPie = (props: ProgressPieProps) => {
+ const {
+ value = 0,
+ padding = 5,
+ size = 50,
+ variant = 'default',
+ ...rest
+ } = props
+ const className = classNames(
+ {
+ 'f-progress-pie': true,
+ },
+ [props.className, getActionClass(variant)]
+ )
+
+ const pieChartPath = useMemo(() => {
+ const realPadding = Math.round((padding / size) * 200)
+ const viewSize = 200 - (realPadding * 2)
+ const radius = viewSize / 2
+ const x = Math.cos((2 * Math.PI)/(100/value))
+ const y = Math.sin((2 * Math.PI)/(100/value))
+ const longArc = (value <= 50) ? 0 : 1
+ const d = "M" + radius + "," + radius + " L" + radius + "," + 0 + ", A" + radius + "," + radius + " 0 " + longArc + ",1 " + (radius + y*radius) + "," + (radius - x*radius) + " z"
+
+ return {
+ d,
+ p: realPadding,
+ }
+ }, [value])
+
+ return (
+
+
- {!!props.children && {props.children}
}
)
}
-export type SubtleProgressProps = {
+export type ProgressSubtleProps = {
value: number
variant?: Variant
} & CoreViewProps
-export const SubtleProgress = (props: SubtleProgressProps) => {
+export const ProgressSubtle = (props: ProgressSubtleProps) => {
const { value = 0, variant = 'default', ...rest } = props
const className = classNames(
{
- 'f-subtle-progress': true,
+ 'f-progress-subtle': true,
},
[props.className, getActionClass(variant)]
)
@@ -120,7 +214,7 @@ export const SubtleProgress = (props: SubtleProgressProps) => {
className={className}>
)}
{progress && (
-