Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addon/components/api/x-class/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { or } from '@ember/object/computed';
import { capitalize } from '@ember/string';
import { capitalize } from '../../../utils/string';
import { memberFilter } from '../../../utils/computed';
import { addonDocsConfig } from 'ember-cli-addon-docs/-private/config';

Expand Down
2 changes: 1 addition & 1 deletion addon/components/api/x-component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { alias, or } from '@ember/object/computed';
import { capitalize } from '@ember/string';
import { capitalize } from '../../../utils/string';
import { memberFilter } from '../../../utils/computed';

export default class XComponent extends Component {
Expand Down
2 changes: 1 addition & 1 deletion addon/components/docs-header/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { classify } from '@ember/string';
import { classify } from '../../utils/string';
import { addonPrefix } from 'ember-cli-addon-docs/utils/computed';
import { inject as service } from '@ember/service';
import { reads } from '@ember/object/computed';
Expand Down
2 changes: 1 addition & 1 deletion addon/components/docs-hero/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
addonPrefix,
unprefixedAddonName,
} from 'ember-cli-addon-docs/utils/computed';
import { classify } from '@ember/string';
import { classify } from '../../utils/string';
import { addonDocsConfig } from 'ember-cli-addon-docs/-private/config';

/**
Expand Down
2 changes: 1 addition & 1 deletion addon/components/docs-viewer/x-nav/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { inject as service } from '@ember/service';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { localCopy } from 'tracked-toolbox';
import { classify } from '@ember/string';
import { classify } from '../../../utils/string';
import { addonLogo } from 'ember-cli-addon-docs/utils/computed';
import { addonDocsConfig } from 'ember-cli-addon-docs/-private/config';

Expand Down
2 changes: 1 addition & 1 deletion addon/helpers/capitalize.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { helper } from '@ember/component/helper';
import { capitalize } from '@ember/string';
import { capitalize } from '../utils/string';

export default helper(function capitalizeHelper(positional) {
return capitalize(positional[0]);
Expand Down
2 changes: 1 addition & 1 deletion addon/models/component.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { attr } from '@ember-data/model';
import { filterBy, or } from '@ember/object/computed';
import { dasherize } from '@ember/string';
import { dasherize } from '../utils/string';

import Class from './class';
import { memberUnion, hasMemberType } from '../utils/computed';
Expand Down
2 changes: 1 addition & 1 deletion addon/utils/computed.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { computed, get } from '@ember/object';
import { capitalize } from '@ember/string';
import { capitalize } from './string';

/**
@function initialize
Expand Down
49 changes: 49 additions & 0 deletions addon/utils/string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Capitalizes the first letter of a string
* @param {string} str - The string to capitalize
* @returns {string} The capitalized string
*/
export function capitalize(str) {
if (!str || typeof str !== 'string') {
return str;
}
return str.charAt(0).toUpperCase() + str.slice(1);
}

/**
* Converts a string to kebab-case (dasherized)
* @param {string} str - The string to dasherize
* @returns {string} The dasherized string
*/
export function dasherize(str) {
if (!str || typeof str !== 'string') {
return str;
}
return str
.replace(/([a-z\d])([A-Z])/g, '$1-$2') // Add dash between camelCase
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1-$2') // Handle consecutive capitals
.replace(/[ _]/g, '-') // Replace spaces and underscores with dashes
.toLowerCase();
}

/**
* Converts a string to PascalCase (classified)
* @param {string} str - The string to classify
* @returns {string} The classified string
*/
export function classify(str) {
if (!str || typeof str !== 'string') {
return str;
}

// If the string contains separators (spaces, dashes, underscores), split and classify
if (/[\s_-]/.test(str)) {
return str
.split(/[\s_-]+/)
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
.join('');
}

// Otherwise, just capitalize the first letter (preserve camelCase like innerHTML -> InnerHTML)
return str.charAt(0).toUpperCase() + str.slice(1);
}
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@
"@ember-data/serializer": "^5.8.0",
"@ember-data/store": "^5.8.0",
"@ember/optional-features": "^2.3.0",
"@ember/string": "^3.1.1",
"@ember/test-helpers": "^3.3.1",
"@ember/test-waiters": "^3.1.0",
"@embroider/test-setup": "^3.0.3",
Expand Down Expand Up @@ -164,7 +163,6 @@
"@ember-data/model": ">= 3.0.0",
"@ember-data/serializer": ">= 3.0.0",
"@ember-data/store": ">= 3.0.0",
"@ember/string": "^3.1.1 || ^4.0.0",
"@ember/test-waiters": "^3.1.0 || ^4.0.0",
"ember-data": ">= 3.0.0",
"ember-inflector": ">= 4.0.0",
Expand Down
6 changes: 0 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion test-apps/new-addon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"test:all": "ember try:each"
},
"dependencies": {
"@ember/string": "^3.1.1",
"ember-cli-babel": "*",
"ember-auto-import": "*"
},
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/helpers/capitalize-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { module, test } from 'qunit';
import { setupRenderingTest } from 'dummy/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { capitalize } from '@ember/string';
import { capitalize } from 'ember-cli-addon-docs/utils/string';

module('Integration | Helper | capitalize', function (hooks) {
setupRenderingTest(hooks);
Expand Down
88 changes: 88 additions & 0 deletions tests/unit/utils/string-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { module, test } from 'qunit';
import {
capitalize,
dasherize,
classify,
} from 'ember-cli-addon-docs/utils/string';

module('Unit | Utility | string', function () {
module('capitalize', function () {
test('capitalizes the first letter', function (assert) {
assert.strictEqual(capitalize('hello'), 'Hello');
assert.strictEqual(capitalize('world'), 'World');
assert.strictEqual(capitalize('innerHTML'), 'InnerHTML');
});

test('handles already capitalized strings', function (assert) {
assert.strictEqual(capitalize('Hello'), 'Hello');
});

test('handles empty strings', function (assert) {
assert.strictEqual(capitalize(''), '');
});

test('handles non-strings', function (assert) {
assert.strictEqual(capitalize(null), null);
assert.strictEqual(capitalize(undefined), undefined);
});
});

module('dasherize', function () {
test('converts camelCase to kebab-case', function (assert) {
assert.strictEqual(dasherize('innerHTML'), 'inner-html');
assert.strictEqual(dasherize('actionName'), 'action-name');
});

test('converts spaces to dashes', function (assert) {
assert.strictEqual(dasherize('my favorite items'), 'my-favorite-items');
});

test('converts underscores to dashes', function (assert) {
assert.strictEqual(dasherize('action_name'), 'action-name');
});

test('handles already dasherized strings', function (assert) {
assert.strictEqual(dasherize('css-class-name'), 'css-class-name');
});

test('handles PascalCase', function (assert) {
assert.strictEqual(dasherize('MyComponent'), 'my-component');
});

test('handles non-strings', function (assert) {
assert.strictEqual(dasherize(null), null);
assert.strictEqual(dasherize(undefined), undefined);
});
});

module('classify', function () {
test('converts kebab-case to PascalCase', function (assert) {
assert.strictEqual(classify('css-class-name'), 'CssClassName');
assert.strictEqual(classify('ember-cli-addon-docs'), 'EmberCliAddonDocs');
assert.strictEqual(classify('addon-docs'), 'AddonDocs');
});

test('converts snake_case to PascalCase', function (assert) {
assert.strictEqual(classify('action_name'), 'ActionName');
});

test('converts space-separated to PascalCase', function (assert) {
assert.strictEqual(classify('my favorite items'), 'MyFavoriteItems');
});

test('preserves camelCase and capitalizes first letter', function (assert) {
assert.strictEqual(classify('innerHTML'), 'InnerHTML');
assert.strictEqual(classify('myComponent'), 'MyComponent');
});

test('handles single words', function (assert) {
assert.strictEqual(classify('component'), 'Component');
assert.strictEqual(classify('Component'), 'Component');
});

test('handles non-strings', function (assert) {
assert.strictEqual(classify(null), null);
assert.strictEqual(classify(undefined), undefined);
});
});
});
Loading