WIP
parent
7dff6bfdef
commit
6f4cd8bff5
@ -1,11 +1,16 @@
|
||||
.buttonSet {
|
||||
display: inline-flex;
|
||||
composes: combinedButton from "../shared.css";
|
||||
}
|
||||
|
||||
.direction-horizontal {
|
||||
grid-auto-columns: 1fr;
|
||||
flex-direction: row;
|
||||
/* composes: combinedHorizontal from "../shared.css"; */
|
||||
/* grid-auto-columns: 1fr; */
|
||||
}
|
||||
|
||||
.direction-vertical {
|
||||
grid-auto-rows: 1fr;
|
||||
flex-direction: column;
|
||||
/* composes: combinedVertical from "../shared.css"; */
|
||||
/* grid-auto-rows: 1fr; */
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const defaultValue = require("default-value");
|
||||
|
||||
const useTheme = require("../../util/themeable");
|
||||
const defaultStyle = require("./style.css");
|
||||
const generateGridItemStyle = require("../../util/generate-grid-item-style");
|
||||
|
||||
function normalizeGridCellSize(value) {
|
||||
if (typeof value === "number") {
|
||||
return `${value}fr`;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function generateGridTemplateString(values) {
|
||||
return values
|
||||
.map((value) => normalizeGridCellSize(value))
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
module.exports = function Grid({ x, y, rows, columns, rowGap, columnGap, children }) {
|
||||
let { withTheme } = useTheme({ control: "grid", defaultStyle });
|
||||
|
||||
let rows_ = defaultValue(rows, [1]);
|
||||
let columns_ = defaultValue(columns, [1]);
|
||||
|
||||
let style = {
|
||||
gridTemplateRows: generateGridTemplateString(rows_),
|
||||
gridTemplateColumns: generateGridTemplateString(columns_),
|
||||
gridRowGap: rowGap,
|
||||
gridColumnGap: columnGap,
|
||||
... generateGridItemStyle({ x, y })
|
||||
};
|
||||
|
||||
// FIXME: Context for x/y
|
||||
|
||||
return (
|
||||
<div className={withTheme("grid")} style={style}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
// return (
|
||||
// <div className="ribbonGrid" style={style}>
|
||||
// {childrenWithProps(props.children, (item) => {
|
||||
// let itemStyle = {};
|
||||
|
||||
// if (item.props.x != null) {
|
||||
// itemStyle.gridColumnStart = item.props.x + 1;
|
||||
|
||||
// if (item.props.cellWidth != null) {
|
||||
// itemStyle.gridColumnEnd = itemStyle.gridColumnStart + item.props.cellWidth;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (item.props.y != null) {
|
||||
// itemStyle.gridRowStart = item.props.y + 1;
|
||||
|
||||
// if (item.props.cellHeight != null) {
|
||||
// itemStyle.gridRowEnd = itemStyle.gridRowStart + item.props.cellHeight;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return {
|
||||
// style: itemStyle
|
||||
// };
|
||||
// })}
|
||||
// </div>
|
||||
// );
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
.grid {
|
||||
display: grid;
|
||||
row-gap: 2px;
|
||||
column-gap: 2px;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const useTheme = require("../../util/themeable");
|
||||
const defaultStyle = require("./style.css");
|
||||
|
||||
module.exports = function MenuDivider() {
|
||||
let { withTheme } = useTheme({ control: "menu", defaultStyle });
|
||||
|
||||
return <hr className={withTheme("divider")} />;
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
.divider {
|
||||
margin: 4px 4px;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const useTheme = require("../../util/themeable");
|
||||
const defaultStyle = require("./style.css");
|
||||
const generateGridItemStyle = require("../../util/generate-grid-item-style");
|
||||
|
||||
module.exports = function ProgressBar({ x, y, progress, color }) {
|
||||
// FIXME: Make color a theme thing
|
||||
let { withTheme } = useTheme({ control: "progressBar", defaultStyle });
|
||||
|
||||
return (
|
||||
<div className={withTheme("bar")} style={generateGridItemStyle({ x, y })}>
|
||||
<div className={withTheme("fill")} style={{width: `${progress * 100}%`, backgroundColor: color}} />
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
.bar {
|
||||
height: 24px;
|
||||
min-width: 16px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fill {
|
||||
height: 100%;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const useTheme = require("../../util/themeable");
|
||||
const defaultStyle = require("./style.css");
|
||||
const generateGridItemStyle = require("../../util/generate-grid-item-style");
|
||||
const Button = require("../button");
|
||||
const ProgressBar = require("../progress-bar");
|
||||
|
||||
module.exports = function ProgressButton({ x, y, horizontal, vertical, type, icon, progress, progressColor, children }) {
|
||||
// FIXME: progressColor in theme, same for custom button style -- maybe make `type` a thing that takes an array, for multiple type classes? to deal with composite controls
|
||||
|
||||
let { withTheme } = useTheme({ control: "progressButton", defaultStyle });
|
||||
|
||||
let direction = (vertical === true)
|
||||
? "vertical"
|
||||
: "horizontal";
|
||||
|
||||
return (
|
||||
<div className={withTheme("progressButton", `direction-${direction}`)} style={generateGridItemStyle({ x, y })}>
|
||||
<Button type={type} icon={icon}>
|
||||
{children}
|
||||
</Button>
|
||||
<ProgressBar progress={progress} progressColor={progressColor} />
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
:import("../progress-bar/style.css") { progressBar: bar; }
|
||||
|
||||
.progressButton {
|
||||
composes: combinedButton from "../shared.css";
|
||||
display: inline-grid;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
|
||||
.progressBar {
|
||||
/* border-top: 0; */
|
||||
}
|
||||
}
|
||||
|
||||
.direction-horizontal {
|
||||
grid-template-columns: auto 1fr;
|
||||
}
|
||||
|
||||
.direction-vertical {
|
||||
grid-template-rows: 2fr 1fr;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const useTheme = require("../../util/themeable");
|
||||
const defaultStyle = require("./style.css");
|
||||
|
||||
module.exports = function RibbonBox({ label, children, width, height }) {
|
||||
let { withTheme } = useTheme({ control: "ribbonBox", defaultStyle });
|
||||
|
||||
// FIXME: How to handle width/height here? Is the current approach correct? Or should we let the user override this through a class?
|
||||
|
||||
return (
|
||||
<div className={withTheme("box")} style={{width: width, height: height}}>
|
||||
<div className={withTheme("contents")}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
<div className={withTheme("label")} title={label}>
|
||||
{label}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
.box {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
margin: 4px 0px;
|
||||
padding: 0px 8px;
|
||||
|
||||
&:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
padding: 1px 5px;
|
||||
font-size: .9em;
|
||||
margin-top: 4px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.contents {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const useTheme = require("../../util/themeable");
|
||||
const defaultStyle = require("./style.css");
|
||||
const generateGridItemStyle = require("../../util/generate-grid-item-style");
|
||||
|
||||
module.exports = function Text({ x, y, align, children }) {
|
||||
let { withTheme } = useTheme({ control: "text", defaultStyle });
|
||||
|
||||
let alignClass = (align != null)
|
||||
? `align-${align}`
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div className={withTheme("text", alignClass)} style={generateGridItemStyle({ x, y })}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
.text {
|
||||
composes: centerContent from "../shared.css";
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
function generateSpecification(coordinates) {
|
||||
if (coordinates == null) {
|
||||
return undefined;
|
||||
} else if (Array.isArray(coordinates)) {
|
||||
let [ start, end ] = coordinates;
|
||||
|
||||
// NOTE: Exclusive -> inclusive conversion for second coordinate
|
||||
return `${start + 1} / ${end + 2}`;
|
||||
} else {
|
||||
return coordinates + 1;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function ({ x, y }) {
|
||||
return {
|
||||
gridColumn: generateSpecification(x),
|
||||
gridRow: generateSpecification(y)
|
||||
};
|
||||
};
|
@ -1,8 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const defaultValue = require("default-value");
|
||||
const insecureNanoid = require("nanoid/non-secure").nanoid;
|
||||
const useGuaranteedMemo = require("./use-guaranteed-memo");
|
||||
|
||||
module.exports = function useID() {
|
||||
return useGuaranteedMemo(() => insecureNanoid());
|
||||
module.exports = function useID(explicitID) {
|
||||
let generatedID = useGuaranteedMemo(() => insecureNanoid());
|
||||
|
||||
return defaultValue(explicitID, generatedID);
|
||||
};
|
||||
|
Loading…
Reference in New Issue