A collection of lightweight, platform-agnostic utility modules designed to accelerate plugin development. These modules provide common functionalities that can be used across any JavaScript/TypeScript project, making them perfect for plugins, extensions, or any web application.
npm install @unoff/utils
# or
yarn add @unoff/utilsConvert strings between different case formats:
import { Case } from '@unoff/utils'
const text = new Case('Hello World Example')
text.doSnakeCase() // 'hello_world_example'
text.doCamelCase() // 'helloWorldExample'
text.doPascalCase() // 'HelloWorldExample'
text.doKebabCase() // 'hello-world-example'Manage feature flags, access control, and cross-platform availability:
import { FeatureStatus } from '@unoff/utils'
// Define your features with editor and service availability
const features = [
{
name: 'PREMIUM_EXPORT',
description: 'Export to premium formats',
isActive: true,
isPro: true,
isNew: false,
limit: 10,
type: 'ACTION',
availabilityForEditors: ['figma', 'dev', 'figjam'],
availabilityForServices: ['BROWSE', 'PARTICIPATE'],
proForServices: ['PARTICIPATE']
}
]
const feature = new FeatureStatus({
features: features,
featureName: 'PREMIUM_EXPORT',
planStatus: 'UNPAID',
currentService: 'PARTICIPATE',
currentEditor: 'figma',
suggestion: 'Upgrade to access premium export features'
})
// Check feature availability and restrictions
console.log(feature.isActive()) // true (feature is active and available for figma)
console.log(feature.isPro()) // true
console.log(feature.isBlocked()) // true (unpaid plan for pro feature)
console.log(feature.isReached(5)) // false (under limit)
console.log(feature.isReached(10)) // true (at limit for unpaid)
// Get suggestion when blocked
if (feature.isBlocked()) {
console.log(feature.isAvailableAndBlocked()) // 'Upgrade to access premium export features'
}Key Features:
- β Cross-platform editor support (Figma, Dev Mode, FigJam, Slides, Penpot, etc.)
- π― Service-specific availability control
- π° Pro/freemium plan management
- π Usage limits and quota tracking
- π New feature flagging
Clean conditional class name concatenation:
import { doClassnames } from '@unoff/utils'
const classes = doClassnames([
'button',
isActive && 'active',
isPrimary && 'primary',
undefined,
null,
]) // Returns: 'button active primary'Transform and manipulate data structures:
import { doMap } from '@unoff/utils'
// Transform arrays with conditional logic
const items = doMap([1, 2, 3, 4], (item) =>
item % 2 === 0 ? item * 2 : null
) // Returns: [4, 8] (filtered out odd numbers)Handle scaling operations for design tools:
import { doScale } from '@unoff/utils'
// Scale values with different algorithms
const scaled = doScale(100, 1.5, 'linear') // Returns: 150All modules come with comprehensive TypeScript definitions:
// Feature types
interface Feature<T> {
name: string
description: string
isActive: boolean
isPro: boolean
isNew: boolean
limit?: number
availabilityForEditors: Array<Editor>
availabilityForServices: Array<T>
proForServices: Array<T>
type: 'SERVICE' | 'DIVISION' | 'ACTION' | 'CONTEXT'
}
type PlanStatus = 'UNPAID' | 'PAID' | 'NOT_SUPPORTED'
type Editor = 'figma' | 'dev' | 'dev_vscode' | 'figjam' | 'slides' | 'penpot' | 'sketch' | 'framer' | 'webflow'- π― Platform Agnostic: Works across all major design tools and development environments
- πͺΆ Lightweight: Each module can be imported independently
- π¦ Zero Dependencies: Pure JavaScript implementations
- π Type-Safe: Written in TypeScript with full type definitions
- π§ͺ Well Tested: Comprehensive test coverage with 100% statement coverage
- π Cross-Platform: Support for Figma, Dev Mode, FigJam, Slides, Penpot, Sketch, and more
- π Feature Management: Built-in support for feature flags, pro plans, and usage limits
import { FeatureStatus } from '@unoff/utils'
// Define features for a multi-platform plugin
const pluginFeatures = [
{
name: 'AI_GENERATION',
description: 'AI-powered content generation',
isActive: true,
isPro: true,
isNew: true,
limit: 5,
type: 'SERVICE',
availabilityForEditors: ['figma', 'figjam', 'penpot'],
availabilityForServices: ['DESIGN', 'PROTOTYPE'],
proForServices: ['DESIGN']
}
]
// Check availability across different contexts
const checkFeature = (editor, service, plan) => {
const feature = new FeatureStatus({
features: pluginFeatures,
featureName: 'AI_GENERATION',
planStatus: plan,
currentService: service,
currentEditor: editor
})
return {
available: feature.isActive(),
blocked: feature.isBlocked(),
isNew: feature.isNew(),
limitReached: feature.isReached(3)
}
}
// Usage examples
console.log(checkFeature('figma', 'DESIGN', 'UNPAID'))
// { available: true, blocked: true, isNew: true, limitReached: false }
console.log(checkFeature('sketch', 'DESIGN', 'PAID'))
// { available: false, blocked: false, isNew: true, limitReached: false }import { Case, doClassnames, FeatureStatus } from '@unoff/utils'
// Transform feature names and create CSS classes
const createFeatureClasses = (featureName, status) => {
const caseTransformer = new Case(featureName)
const baseClass = caseTransformer.doKebabCase()
return doClassnames([
`feature-${baseClass}`,
status.isActive() && 'active',
status.isPro() && 'pro',
status.isNew() && 'new',
status.isBlocked() && 'blocked'
])
}| File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
|---|---|---|---|---|---|
| All files | 100 | 98.75 | 100 | 100 | |
| case | 100 | 100 | 100 | 100 | |
| case.ts | 100 | 100 | 100 | 100 | |
| do-classnames | 100 | 100 | 100 | 100 | |
| do-classnames.ts | 100 | 100 | 100 | 100 | |
| do-map | 100 | 100 | 100 | 100 | |
| do-map.ts | 100 | 100 | 100 | 100 | |
| do-scale | 100 | 95.45 | 100 | 100 | |
| do-scale.ts | 100 | 95.45 | 100 | 100 | 41 |
| feature-status | 100 | 100 | 100 | 100 | |
| feature-status.ts | 100 | 100 | 100 | 100 |
# Install dependencies
npm install
# Run tests
npm test
# Build the library
npm run buildWe welcome contributions! Please see our contributing guidelines for details.
This project is licensed under the MIT License - see the LICENSE file for details.