@activecollab/components
Version:
ActiveCollab Components
217 lines (209 loc) • 8.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.FeatureAvailability = exports.DEFAULT_FEATURE_AVAILABILITY = void 0;
var _react = _interopRequireDefault(require("react"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* FeatureAvailability — a compact, data-driven block that states where a
* feature is available: on which hosting, on which plans and to which roles.
*
* It is the reusable version of the availability panel used in the Help Docs
* example articles, extracted so several stories (and, later, the real
* PortableText renderer) can share one implementation and one visual language:
*
* • green check → available
* • analog clock → decided but not shipped yet ("to be determined")
* • strikethrough → not included
*
* The component is theme-agnostic (all colors come from `--color-*` tokens) and
* self-contained (it carries its own typography, so it renders correctly
* outside the article body as well).
*/
/* ------------------------------------------------------------------ */
/* Marks */
/* ------------------------------------------------------------------ */
var CheckMark = function CheckMark() {
return /*#__PURE__*/_react.default.createElement("svg", {
className: "ap-ic ap-yes",
viewBox: "0 0 16 16",
width: "15",
height: "15",
"aria-hidden": true
}, /*#__PURE__*/_react.default.createElement("path", {
d: "M13 4.6 L6.5 11.4 L3 8",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round"
}));
};
var ClockMark = function ClockMark() {
return /*#__PURE__*/_react.default.createElement("svg", {
className: "ap-ic ap-clock",
viewBox: "0 0 16 16",
width: "14",
height: "14",
"aria-hidden": true
}, /*#__PURE__*/_react.default.createElement("circle", {
cx: "8",
cy: "8",
r: "6.2",
fill: "none",
stroke: "currentColor",
strokeWidth: "1.4"
}), /*#__PURE__*/_react.default.createElement("path", {
d: "M8 8 L8 4.4 M8 8 L10.5 9.3",
fill: "none",
stroke: "currentColor",
strokeWidth: "1.4",
strokeLinecap: "round"
}));
};
var StatusIcon = function StatusIcon(_ref) {
var status = _ref.status;
if (status === "available") {
return /*#__PURE__*/_react.default.createElement(CheckMark, null);
}
if (status === "pending") {
return /*#__PURE__*/_react.default.createElement(ClockMark, null);
}
return null;
};
/** A nested mark inside parentheses, e.g. "PM ✓". */
var ChildMark = function ChildMark(_ref2) {
var mark = _ref2.mark;
return mark.status === "excluded" ? /*#__PURE__*/_react.default.createElement("span", {
className: "ap-excluded"
}, mark.label) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, mark.label, " ", /*#__PURE__*/_react.default.createElement(StatusIcon, {
status: mark.status
}));
};
var Mark = function Mark(_ref3) {
var _mark$children;
var mark = _ref3.mark,
iconPosition = _ref3.iconPosition;
var hasChildren = Boolean(mark.children && mark.children.length > 0);
var excluded = mark.status === "excluded";
var icon = hasChildren ? null : /*#__PURE__*/_react.default.createElement(StatusIcon, {
status: mark.status
});
return /*#__PURE__*/_react.default.createElement("span", {
className: excluded ? "ap-item ap-excluded" : "ap-item"
}, iconPosition === "before" && icon, mark.label, mark.note && /*#__PURE__*/_react.default.createElement("span", {
className: "ap-sub"
}, mark.note), mark.pending && /*#__PURE__*/_react.default.createElement("span", {
className: "ap-tbd"
}, mark.pending), hasChildren && /*#__PURE__*/_react.default.createElement("span", {
className: "ap-sub"
}, "(", (_mark$children = mark.children) === null || _mark$children === void 0 ? void 0 : _mark$children.map(function (child, index) {
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
key: child.label
}, index > 0 && " / ", /*#__PURE__*/_react.default.createElement(ChildMark, {
mark: child
}));
}), ")"), iconPosition === "after" && icon);
};
/* ------------------------------------------------------------------ */
/* Panel */
/* ------------------------------------------------------------------ */
var StyledPanel = _styledComponents.default.div.withConfig({
displayName: "FeatureAvailability__StyledPanel",
componentId: "sc-42kyhy-0"
})(["font-family:-apple-system,BlinkMacSystemFont,\"Roboto\",\"Helvetica Neue\",Arial,sans-serif;font-size:13px;line-height:20px;color:var(--color-theme-900);padding:12px 16px;border:1px solid var(--color-theme-300);border-radius:10px;background:var(--color-theme-100);.ap-row{display:flex;gap:10px;padding:6px 0;align-items:baseline;flex-wrap:wrap;}.ap-row:first-of-type{padding-top:0;}.ap-row:last-of-type{padding-bottom:0;}.ap-row + .ap-row{border-top:1px dashed var(--color-theme-300);}.ap-label{flex:0 0 84px;color:var(--color-theme-700);font-weight:600;font-size:13px;}.ap-vals{flex:1 1 240px;display:flex;flex-wrap:wrap;gap:4px 14px;align-items:center;}.ap-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap;}.ap-sub{color:var(--color-theme-600);}.ap-tbd{color:var(--color-theme-600);font-style:italic;}.ap-sep{color:var(--color-theme-400);}.ap-excluded{text-decoration:line-through;color:var(--color-theme-500);}.ap-ic{flex:none;vertical-align:-2px;}.ap-yes{color:var(--color-green-olive-drab);}.ap-clock{color:var(--color-theme-600);}"]);
var FeatureAvailability = exports.FeatureAvailability = function FeatureAvailability(_ref4) {
var rows = _ref4.rows,
className = _ref4.className;
return /*#__PURE__*/_react.default.createElement(StyledPanel, {
className: className,
"aria-label": "Feature availability"
}, rows.map(function (row) {
var _row$iconPosition;
var iconPosition = (_row$iconPosition = row.iconPosition) !== null && _row$iconPosition !== void 0 ? _row$iconPosition : "after";
return /*#__PURE__*/_react.default.createElement("div", {
className: "ap-row",
key: row.label
}, /*#__PURE__*/_react.default.createElement("span", {
className: "ap-label"
}, row.label), /*#__PURE__*/_react.default.createElement("span", {
className: "ap-vals"
}, row.items.map(function (item, index) {
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
key: item.label
}, index > 0 && row.separated && /*#__PURE__*/_react.default.createElement("span", {
className: "ap-sep"
}, "\xB7"), /*#__PURE__*/_react.default.createElement(Mark, {
mark: item,
iconPosition: iconPosition
}));
})));
}));
};
/* ------------------------------------------------------------------ */
/* Illustrative defaults */
/* ------------------------------------------------------------------ */
/**
* A realistic GA feature: shipped on Cloud, self-hosted still to be scheduled,
* on every plan, for internal roles but not for clients. Exercises all three
* marks (check / clock / strikethrough) out of the box.
*/
var DEFAULT_FEATURE_AVAILABILITY = exports.DEFAULT_FEATURE_AVAILABILITY = {
rows: [{
label: "Availability",
iconPosition: "before",
separated: true,
items: [{
label: "Cloud",
status: "available",
note: "(stable, since Jun 17 2026)"
}, {
label: "Self-Hosted",
status: "pending",
pending: "to be determined"
}]
}, {
label: "Plans",
items: [{
label: "S–Mega",
status: "available"
}, {
label: "Plus",
status: "available"
}, {
label: "Pro",
status: "available"
}, {
label: "Pro+Get-Paid",
status: "available"
}]
}, {
label: "Roles",
items: [{
label: "Owner",
status: "available"
}, {
label: "Member",
status: "available"
}, {
label: "Member+",
status: "available",
children: [{
label: "PM",
status: "available"
}, {
label: "FM",
status: "available"
}]
}, {
label: "Client",
status: "excluded"
}, {
label: "Client+",
status: "excluded"
}]
}]
};
//# sourceMappingURL=FeatureAvailability.js.map